1
votes

I have a lot of code that uses a ViewModelLocator to set the datacontext on views.

I'm currently using a simple service locator (Simple Injector / CuttingEdge.ServiceLocation) so that the ViewModelLocator with a parameterless constructor can be instantiated from XAML in Window or UserControl.Resources and then used to set the DataContext.

I'm in the process of changing to use Ninject and thought I'd be able to continue to use the ViewModelLocator in the same way. However, I've now found that Ninject doesn't directly support service location (and it appears that service location is a concept that has fallen out of favor).

I'd like to continue to specify a views viewmodel from XAML (using a ViewModelLocator derived class) but I can't find a tidy was of doing this with Ninject.

I can't find any way of doing this. How are other developers doing this without a IoC container that supports IServiceLocator (or similar)?

Notes:

1
Have you seen this NuGet project? I haven't tried it, but it claims to enable ServiceLocation with Ninject. nuget.org/packages/Web.ServiceLocator.NinjectMcGarnagle
@McGarnagle - Yes thanks, I have seen that but I was hoping to find a solution that didn't involve a servicelocator.grantnz

1 Answers

2
votes

Indeed service locator as a concept is falling out of favor. But sometimes as described in your case when you do ViewFirst approach you need to instantiate the ViewModel in the XAML markup. I strongly advice not to do so and fall back to the ViewModelFirst approach but I understand that you cannot change the whole world at a time. The original caliburn framework had markup extensions which allowed to resolve instances from the XAML code. Caliburn had some sort of container abstraction which was accessible from the IoC static class. You can find the markup code here:

http://caliburn.codeplex.com/SourceControl/latest#src/Caliburn.PresentationFramework/ResolveExtension.wpf.cs

I advice that you don't use service locator abstractions as in Microsoft Common Service Locator but directly call into your static global IResolutionRoot and resolve instances from there with the custom implemented markup extension. That shouldn't be too hard to implement. As soon as you have that in place I would start redesigning your solution into a VMFirst approach so that you can remove the need to resolve dependencies by Locator and lean to a more inversion of control approach.