williamsandonz
williamsandonz

Reputation: 16420

Do I pass singletons as parameters or do I manually resolve them? (Unity DI)

I am using unity mvc4 package, it is auto injecting into my controllers fine. But now I am manually doing other parts of my application, helpers etc.

How can I access the singletons within the container from other classes?

How do I call MethodWithDependency(param) on my instance of MyClass2? Am I supposed to do the below? It looks far too messy.

public class MyClass1
    {
        public void Main()
        {
            var myObject2 = container.Resolve<MyClass2>;
            var someObject = container.Resolve<SomeClass>;
            myObject2.MethodWithDependency(someObject);
        }
    }

    public class MyClass2
    {
        public void MethodWithDependency(SomeClass someObject)
        {
        }
    }

Upvotes: 0

Views: 193

Answers (2)

Chris Leyva
Chris Leyva

Reputation: 3526

Create MyClass2 so that it accepts SomeClass as an argument in the constructor (you are injecting the SomeClass dependency into your MyClass2 object).

Then, you can register your Instances with the Container. At that point, when you resolve your MyClass2 object, your SomeClass object will also be resolved and injected into MyClass2.

Beautiful, huh?

The Code

public class MyClass1
{
    private UnityContainer _container;

    public void Main()
    {
        this.RegisterContainer();

        // Since SomeClass was registered, when you resolve MyClass2, it will
        // magically resolve an instance of SomeClass that the MyClass2 
        // constructor needs.
        var myObject2 = this._container.Resolve<MyClass2>;

        myObject2.MethodWithDependency();
    }

    private void RegisterContainer()
    {
        // Here, initialize your Container then register your singletons.
        this._container = new UnityContainer();

        // Do not use container.RegisterType<>()....
        // RegisterInstance, by default, implements a singleton behavior.
        this._container.RegisterInstance<SomeClass>();
        this._container.RegisterInstance<MyClass2>();
    }
}

public class MyClass2
{
    private SomeClass _someClass;

    // You are injecting the SomeClass dependency into your MyClass2 class.
    // Hence the name — Dependency Injection.
    public MyClass2(SomeClass someClass)
    {
        this._someClass = someClass;
    }

    public void MethodWithDependency()
    {
        // use your _someClass object.
        this._someClass.DoSomething();
    }
}

Upvotes: 2

Wiktor Zychla
Wiktor Zychla

Reputation: 48230

Each object that needs its dependencies resolved can potentially have them resolved by the container. To not to spoil your code with containers, you create local factories and implement specific factory providers elsewhere, in the Composition Root which is the only place in your application where container is created and used directly.

This requires discipline, however you are able to structure your code so that there is no explicit reference to the container except for the Composition Root and still container does the job.

I wrote a tutorial on that once, it is too long to quote it here:

http://www.wiktorzychla.com/2012/12/di-factories-and-composition-root.html

Answering your specific question: to have singletons you just use the ContainerControllerLifetimeManager as the parameter to the register method.

http://msdn.microsoft.com/en-us/library/ff660872(v=pandp.20).aspx

Upvotes: 4

Related Questions