Using UnityContainer without constuctor injection

Topics: Prism v1
Jun 4, 2009 at 3:59 PM

Hi there,

The following is a typical code of using the UnityContainer with constructor injection.

public class MyClass : IModule

{

        private IUnityContainer myContainer;

        public MyClass(IUnityContainer container)
        {
            myContainer = container;
        }
}

But I want to avoid this constructor injection way. So, how to use the UnityContainer without using constructor injection?

Thanks,

Jie

 

Jun 4, 2009 at 4:54 PM

Hi Jie,

 

I don't know your scenario, but if for some reason you want to avoid constructor injection, you might inject object dependencies using Property Injection. To achieve this you can decorate class properties as follows:

 

  [Dependency]

  public YourType YourProperty {get; set;}

 

For more information about this topic  you can check:

·         Introduction to Unity

·         Dependency Injection Types and Mappings

 

For more information about Unity you might check Unity Application Block at MSDN and you might find useful the Hand-on-Labs that where recently published: Hands-On Labs for the Unity Application Block 1.2.

 

Please let me know if this helps.

 

Matias Bonaventura

http://blogs.southworks.net/matiasb

Jun 5, 2009 at 4:22 PM

Hi Matias,

Thanks for your reply and info, which helped me to have a better understanding on the unity container. I also did some of the HOL. BTW, Lab02 didn't compile on VS2008 for the following line:

    container
        .RegisterType<IStockQuoteService, MoneyCentralStockQuoteService>(
            new InjectionProperty("Logger"))

However, for my issue, I need further help. I have three modules (projects): IService, Service, and Client. In the Service module, it has the implementation of the IService interface. And it also registers the IService and Service:

namespace MyService
{
    Public class Service : IService
    {
        // IService implementation
    }

    public class ServiceModule : IModule
    {
        private IUnityContainer uContainer;

        public Service(IUnityContainer container)
            {
                this.uContainer = container;
            }

            public void Initialize()
            {
                RegisterServices();
            }

        protected void RegisterServices()
        {
            this.uContainer.RegisterType<IService, Service>();
        }
    }
}

I used the Separated Interface pattern to have IService and Service in two separate modules (projects). The third module, client, uses the Service as below:

namespace MyClient
{
    public class Client : IModule
    {
        private IUnityContainer uContainer;
        private IService service;

        public Client(IUnityContainer container)
        {
            this.uContainer = container;
            service = uContainer.Resolve<IService>();
        }
    }
}

This way, the Client module does not have any dependency on the Service module, and all code works fine.

But now, due to some other designs, I want to remove the constructor injection for the Client class, i.e., to have a class and its constructor like this:

namespace MyClient
{
    public class Client
    {
        public Client()
        {
        }

    }

}

The Client class needs to be instantiated by another class, which does not have anything to do with the UnityContainer. Meanwhile, I want to keep the separated interface pattern design.

How can I accomplish this?

Thanks,

Jie

 

Jun 5, 2009 at 9:07 PM

Hi Jie,

 

I would divide the problem in two: on one side the separated interface pattern and on the other the use of unity. The separated interface pattern does not necessarily need to be tied to Unity or any container (although I personally think they plug together nicely).

 

If you want properties and other injection performed to an instance when you do not control its construction, you can use the BuildUp method of the Unity container. This will make the object go through the container strategies that can be executed after object creation, such as property or method injection. This approach might help you inject some dependencies in your client event if it's not initialized by Unity.

            For more information about BuildUp method you can check:

·         Using BuildUp to Wire Up Objects Not Created by the Container

 

 

The separated interface pattern will help you reduce coupling between modules and the service by keeping the service interface and its implementation in separated packages. Besides the service implementation and the service interface you will also need someone to tight them: instantiate the service, keep it's reference and make it accessible to clients (this is the data mapper on Martin Fowler's Separated Interface pattern). Unity is a very good choice for the data mapper in the pattern as it not only keeps the service reference, but it is also flexible, decoupled from the business logic, can inject dependencies, etc, etc.

 

If for some reason you can't use unity infrastructure in your client, you will need to build your own data mapper. One way to implement the datamapper might be by creating a static class that exposes a GetService method that returns an IService. The datamapper might be placed in the Infrastructure to make it available to all modules. If the scenario allows you, you might use unity to return the service. If not, you can manfully maintain a static reference to the service instance and return it:

 

public static class ServiceFactory

{

    private static IService myService;

 

    public static IService MyService

    {

        get

        {

            return myService;

        }

        set

        {

            myService = value;

        }

    }

}

 

Your service module will have to register the service in the ServiceFactory instead of using unity.

 

The following links might proviede deals with some of the concepts I have mentioned above:

·         Separated Interface pattern on Martin Fowler's Web site

·         Patterns in the Composite Application Library

 

Hope it helps!

 

Matias Bonaventura

http://blogs.southworks.net/matiasb