Support for composite applications

Jun 9, 2011 at 7:44 PM

We have an extensible WPF application built on the Prism framework. This allows developers to write modules that plugin and extend our basic shell application. For these module developers we use NuGet to do 2 things:

  1. Automatically references our contract assemblies that allow the modules to communicate with the shell. We distribute these in the lib folder. 
  2. Debug their module project using a working copy of the shell application. We distribute this in the tools folder. Our package adds a powershell command "Update-DebuggerSettings" that will modify debugger settings in all projects that reference the shell package to point at the exe in the tools folder.

Here are some of the pain points we are experiencing:

  • In our shell application we reference many other NuGet packages. e.g. Automapper, Moq, Rx, Prism, Unity etc. We declare these as dependencies in our nuspec. When module developers reference our shell package they get a ton of references added to their project that they may or may not need.
  • If a module developer wants to use a NuGet package that the shell is already referencing (e.g. Automapper) it would be nice if our shell package could limit what versions are available for them to add to their project. Currently this is the only reason we declare a dependency on things like Automapper and Moq in our shell package which bloats the module developer's initial package references.
  • Packages are stored in a folder with the version number. This requires module developers to update their debugger setting every time they update the package. As I understand it, this will be changing in NuGet 1.4.
Jun 9, 2011 at 10:38 PM
Edited Jun 9, 2011 at 10:38 PM
xpando wrote:
  • In our shell application we reference many other NuGet packages. e.g. Automapper, Moq, Rx, Prism, Unity etc. We declare these as dependencies in our nuspec. When module developers reference our shell package they get a ton of references added to their project that they may or may not need.

I'm not clear about your "shell application"? What is it? Is it the package that contains your contract assemblies? Why does it need to reference the other packages?

I believe you can refactor your contract assemblies such that it doesn't depend on Automapper, Moq, etc. Then you can package just those assemblies.

Jun 10, 2011 at 2:25 AM

The contract assemblies do not depend on any NuGet packages. Just .NET framework assemblies. Unlike a web application though plugins to our application are hosted by our shell exe. This means that if our shell exe references a nuget package like Automapper and a module developer later nugets in an incompatible version of automapper their plugin cannot be hosted in our shell exe anymore. Granted the fix is for the module developer to go back and ref a compatible version of automapper but its these kinds of version conflicts that nuget is intended to take care of. 

Here's an example:

MyApp NuGet Package

MyApp.Contracts.dll

References only .NET framework

Packaged in lib folder of NuGet package so that plugins get a reference to it

Packaged in tools folder with MyApp.exe so that it can be executed as the startup app for modules developers.

MyApp.EXE

Has project reference to MyApp.Contracts

References Prism, Automapper and Moq NuGet packages.

Packaged in tools folder with myapp.contracts.dll, automapper.dll and moq.dll.

Init.ps1 adds a command to the package manager console so that a module developer can Update-DebuggerSettings. This sets the debugger to launch MyApp.EXE from the tools folder and passes a command line parameter to the module's build output folder to load the module as a plugin at runtime.

MyModulePlugin.dll

References MyApp NuGet package

Runs Update-DebuggerSettings command added by nuget package which sets MyApp.exe as the startup app for this project

If I reference an incompatible version of Automapper in this project I will break MyApp.exe. This is where I would like to have the MyApp NuGet package declare that it uses Automapper version x.y.z and only allow the MyModulePlugin project to reference that version of Automapper. NOTE: it should also set the reference to automapper as copy local false since the assembly will be part of the main application's bin folder.