IUnityContainer as Singleton

Topics: Prism v2 - Silverlight 4
May 20, 2010 at 6:01 PM

Hi Guys,

I've been studying Prism for past two days and have a question - why not have a Singleton instance of a IUnityContainer instead of injecting it everywhere, what's the point of writing additional code, I just dont get it. I'm building an Silverlight app using the MVVM model and want to use the IUnityContainer to resolve services inside my ViewModels. Also I'd like my ViewModels to be declared in the xaml resources, it brings some advantages with it. If I want to use Prism (Unity) I end up in an situation (which is shown in one of the prism videos) where the service is manually attached to the ViewModel from the View, it's too laborious and ugly. It might be that I'm missing something, any thoughts are very welcome.

Regards,

Stevo

Developer
Jun 2, 2010 at 7:08 PM

Hi Stevo,

Each time you inject the UnityContainer, the same instance is resolved, since internally it is registered as a Singleton instance. You can confirm that by checking the HashCode of the different references to the container throughout your application; they are the equal, showing that they all point to the same instance.

If you are referring to having, for example, a static property instead of injecting the container, you must take into account that in that case you would have a direct reference to that static property in every component that uses the container, thus losing the benefits of Dependency Injection. That is, you would lose testability, as well as lifetime management for the container itself, among other benefits.

On the other hand, if you want your ViewModel to get a reference to a service, a possible approach would be to use Constructor Injection. It’s not necessary to inject the Unity Container and then resolve the services through it. The code for that would look like this:

public MyModuleViewModel(IService myService, IAnotherService myOtherService)

{

this.myService = myService;

this.myOtherService = myOtherService;

(…)

}

As for declaring the ViewModel in XAML resources, if you meant that you would prefer to instantiate the ViewModel directly in the XAML, like this:

<UserControl.DataContext>
<MyViewModel/>
</UserControl.DataContext>

you would be losing the benefits of Constructor Injection, as the XAML would be instantiating the ViewModel through a default constructor (if the ViewModel didn’t have one, it would throw an exception).

The classic approach to have access to the ViewModel in the View’s XAML is to add the ViewModel as the DataContext of the View programmatically. The code for that would look like this:

public MyView(IMyModuleViewModel viewModel) { InitializeComponent(); this.DataContext = viewModel; }

That way you would have access to the ViewModel from your XAML, when you use bindings.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Jun 3, 2010 at 10:59 AM

Hi Guido,

 

thanks for the reply. I understand most of the things what you refer to. However I don't understand how would I loose testability (I can assign whatever instance I want to to the static singleton property that can be available during testing) and what exactly you mean by lifetime managment (One signleton that's alive as long as the application is alive)?

Our application structure is following - main silverlight + .web projects and X-number of modules (other projects). The main silverlight project has Shell, bootstrapper, DomainContexts, service interfaces and lots of common classes in it. Each module has the main references the main silverlight application and implements its own specific views and services, thus has access to all the common stuf, where the UnityContainer singleton resides.

Regards,

Stevo

Oct 15, 2010 at 9:28 PM

Hi,

If you followed the approach you’ve mentioned, you would be losing lifetime management because, if you use a static property, that instance of the container will be kept in memory for as long as the application runs. You can read more about Lifetime Managers in this article from the Unity Documentation.

As for the loss of testability, although you would be able to mock the implementation of the container by assigning whatever instance you want to the static property, that would imply mixing your production code with your testing code. If, for example, you had the following code:

public class MyClass
{
    private IUnityContainer container;
    public MyClass()
    {
        container = StaticContainer.GetInstance();
    }
}

public class StaticContainer
{
    private static IUnityContainer container;
    public static bool Testing;
    public static IUnityContainer GetInstance()
    {
        if StaticContainer.Testing
            return MockContainer();

        if container == null
            container = new UnityContainer();
        return container;
    }
}

You would give the production code the possibility of running the mock instances. In addition to that, in case there were a large number of different mocks, the StaticContainer class would have to be responsible for knowing which mock to use.

 

Fernando Antivero
http://blogs.southworks.net/fantivero