Unity IOC Container. How to resolve instance from IOC container outside of the scope where container was created?

58 Views Asked by At

I am new to IOC containers and i am trying to understand how to use them. I understand the concept but I having issues on how to practically apply it. Currently, I am using Unity ioc container to register an instance of a RestClient for a web api wrapper class and then injecting said instance to a class that handles the different requests. see code below:

var myClient = new RestClient();
var iocContainer = new UnityContainer();
iocContainer.RegisterInstance(myClient);
iocContainer.RegisterType<MyWrapperClass>(
new InjectionConstructor(iocContainer.Resolve<RestClient>()));

This code is happening in the OnStartup file of my wpf application. If I want to get that object that was register I know i can call iocContainer.Resolve<MyWrapperClass>() however, if how can I resolve that object in a different class where the Ioc does not live?

Hopefully my explanation makes sense. Any help is appreciated.

2

There are 2 best solutions below

0
Mark Seemann On

The best way to use a DI Container is to use the Register Resolve Release pattern. Instead of sprinkling your entire code base with calls to container.Resolve, you should have one line of code in your code base that calls Resolve. That line of code, then, composes the entire object graph that implements the behaviour of the application.

(Really, you don't need a DI Container to do that, and I consider Pure DI a much simpler solution to the same problem.)

When an object needs to talk to another object, let it request the dependency via its constructor, e.g.:

public MainWindow(IDep dep) { /*...*/ }

It's been a decade since I've last looked at WPF, but the first edition of my book Dependency Injection in .NET has a section that covers WPF composition (and a chapter on Unity, too). That edition is also available as a free eBook with the latest edition of the book.

14
mm8 On

however, if how can I resolve that object in a different class where the Ioc does not live?

You need to get a reference to the container one way or another.

You could for example define a static property in the App class:

public partial class App : Application
{
    public static IUnityContainer Container { get; } = new UnityContainer();

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        var myClient = new RestClient();
        var iocContainer = Container;
        iocContainer.RegisterInstance(myClient);
        iocContainer.RegisterType<MyWrapperClass>(
            new InjectionConstructor(iocContainer.Resolve<RestClient>()));
    }
}

You can then easily resolve a type from a component in your app like this:

var wrapperClass = App.Container.Resolve<MyWrapperClass>();