Dependency Injection, Best Practices?

Jan 31, 2011 at 9:35 PM
Edited Jan 31, 2011 at 9:36 PM

I am having some contention with exactly how I should structure my ViewModels that have both parameters and injected dependencies.  For example, say that I have a particular ViewModel that implement an interface like IWorkspace, very similar to Rob's Hello Screens sample application.  After activating this workspace in the shell, I then activate a ListViewModel within the workspace, which shows a whole bunch of list items.  Here is where it gets a little fuzzy.  Suppose that after a user clicks on a list item, I want to load a DetailViewModel, which is defined like so:

public class DetailViewModel : Screen, IHandle<SomeMessage>
	int id;
	public IEventAggregator EventAggregator { get; set; }
	public IWindowManager WindowManager { get; set; }
	public DetailViewModel(int id)
	{ = id;

	// ...

My first question is, what is considered best practice when instantiating a ViewModel such as this?  The id will be used to fetch an entity's details from the server, but I don't think this argument goes into IoC, right?  Plus, keen developers will notice that the code above will throw a null reference exception because I am using EventAggregator in the constructor, which hasn't been resolved by IoC.  That's because in the ListViewModel, I instantiate with this code:

var details = new Campaigns.IndexViewModel(2385);
//Show details

So assuming I am taking the right approach, where should I be initializing code that requires dependencies to already be resolved (such as EventAggregator.Subscribe(this))?

Also, ideally I'd like to do constructor injection so that my classes are not publicly exposing their dependencies, but this would muddy my code even further.  I'd love some input as to how developers are handling these situations.



Jan 31, 2011 at 9:43 PM
Edited Jan 31, 2011 at 10:19 PM

Also, it is worth pointing out that sometimes I have to show a view that is in another unreferenced assembly.  This looks something like:


yield return Show.Screen<IDetailScreen>(Keys.ContractNames.EntityDetail).In<IShell>().Configured(screen =>
	screen.Id = SelectedTopSpending.Id;


Here I am relying on MEF to resolve a named instance of an interface, which works nicely.  However, the Id in this scenario is forced to be a public property in order to properly configure the view instance.  Therefore, very little initialization code can reside inside of the concrete IDetailScreen's constructor.  

Should I just abandon constructor initialization, and make all required parameters as public properties to gain some consistency?

Jan 31, 2011 at 10:10 PM

I normally use ctor injection for required services. Then, I add some sort of method to initialize the data.

var viewModel = CreateViewModel().WithCampaign(2385);


Jan 31, 2011 at 10:17 PM


I use very similar to EisenbergEffect

All REQUIRED dependencies are injected thru the constructor... it makes them more visible

Optional Dependencies I would inject using property injection 

Params I pass in thru a method to init the data

.. this way you knwo that IF the instance has been created without throwing any exceptions then it is in a usable state ...



Jan 31, 2011 at 11:35 PM
Edited Jan 31, 2011 at 11:40 PM

I'm starting to see the benefits of delegating instantiation to a method.  Stooboo, I like your rules for dependencies and parameters.  The only part I don't understand is how you can guarantee that your instance is in a usable state, even when you are passing required params into an optional init method.


Rob, I am liking the idea of using a factory to instantiate ViewModels on my behalf, and injecting the factory.  I see you accomplish this in HelloScreens with the bootstrapper:


            batch.AddExportedValue<Func<OrderViewModel>>(() => container.GetExportedValue<OrderViewModel>());


However, there is some complexity that occurs when dynamically loading xaps;  you cannot just setup these factories in the main bootstrapper during bootup.

One way to solve the problem is to have something like IConfigure, and have concrete implementations in each of the dynamically loadable xaps.  Then, when the Catalog is downloaded, I can search for these parts and execute them, passing in the container.  This gives the xap a chance when it is loaded to add all of the factories (or other dependencies) it needs into the container, so that they are available for injection:

var configurators = downloadedCatalog.Parts
	.Where(part => ReflectionModelServices.GetPartType(part) is IConfigure);

foreach(var configure in configurators)

What do you think?



Feb 1, 2011 at 12:15 AM

When I say 'usable' I mean it has all the components it depends on e.g. repositories, service-wrappers etc

It's initial 'state' will be fairly blank/null  ....

until (one of) the Init method(s) is called...

which would initiate it's 'state' change  .... (e.g. pass in an Id and it will call a repository to get the entity, ... or even just pass it the entity  )

This works for me but I don;t think I'm great at explaining/justifying it ;-)


..if you're using MEF , for factories you could always inject an ExportFactory<TTypeIWantToCreateSomeOfLater> into your constructor

then you can control the disposal of the instances you create (if you want them non-shared)... 





Feb 1, 2011 at 12:55 AM


Have a look at ExportFactory<T> It is available in the SL version of MEF. It's technically the right way to do factories in MEF. I didn't know about it when I wrote that sample. It will probably solve that part of the problem for you.

Feb 1, 2011 at 4:32 AM

ExportFactory sounds perfect.  I'm using MEF for silverlight, but I don't see ExportFactory anywhere (I'm referencing c:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.ComponentModel.Composition.dll)

Do I have to download a preview version to get this feature?


Feb 1, 2011 at 5:33 AM

I found ExportFactory; it was hiding in another dll:

c:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.ComponentModel.Composition.Initialization.dll

stooboo, thanks for your feedback!

Rob, thanks for your quick advice, and this extraordinary framework.  It really facilitates the ability to create an amazing foundation for applications.  I look back on my usage of MVVM Light, and it all seems like child's play now :)

Jan 10, 2012 at 8:25 AM
EisenbergEffect wrote:

I normally use ctor injection for required services. Then, I add some sort of method to initialize the data.

var viewModel = CreateViewModel().WithCampaign(2385);


Dear Rob (or Community)

could you please post a quick sample how I could implement this?

Actually I have the same question/problem, that I have some parameters I probably wouldn't like to register with MEF an
I have no Idea if using IoC.BuildUp would be bad style.

Jan 10, 2012 at 2:54 PM

In general, you should avoid using IoC.BuildUp unless you are using it very-low level in your infrastructure. For an example of how you can do some of the things discussed above, have a look at the HelloScreens sample. It has some bugs now, I think, but it should give you some ideas for how you can use the container by injecting factories. The new version of MEF (or the current Silverlight version) has some new factory features that make this sort of things even easier.

Jan 11, 2012 at 8:35 AM
Edited Jan 11, 2012 at 11:28 AM


so there are three possibilities as long as I see:

1) Any constructor-parameter has to be exported. (This is what I cant guarantee always)

2) Avoid any non-registered ctor-parameters. Use Something like ".WithX(y)"  as above.
    But then they are no longer mandatory!

3) use of IoC.BuildUp, but that seems to be bad style.

Hm....don't really like any of the three possibilities.


Edit: Found a nice hint to an abstract Factory.

Jan 11, 2012 at 2:35 PM

You should really look at the HelloScreens sample, which demonstrated factories with IoC.

Jan 11, 2012 at 2:55 PM

I have done this. Probably you mean the Func<ViewModel> which I really Like.

But the Stackoverflow-Link would be an alternative with non-registered-parameters.

But I will take a deeper look into your HelloScreens sample again.

Jan 11, 2012 at 4:44 PM

I think, in your case you could use a combination of the two techniques depending on the situation.