简体   繁体   中英

Unity Dependency Injection

I've been reading the following guide on Unity and dependency injections: https://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx

and I've come across something that confused me:

Using the Unity container, you can register a set of mappings that determine what concrete type you require when a constructor (or property or method) identifies the type to be injected by an interface type or base class type. As a reminder, here is a copy of the constructor in the ManagementController class showing that it requires an injection of an object that implements the ITenantStore interface.

 public ManagementController(ITenantStore tenantStore) { this.tenantStore = tenantStore; }

The following code sample shows how you could create a new Unity container and then register the concrete type to use when a ManagementController instance requires an ITenantStore instance.

 var container = new UnityContainer(); container.RegisterType<ITenantStore, TenantStore>();

The RegisterType method shown here tells the container to instantiate a TenantStore object when it instantiates an object that requires an injection of an ITenantStore instance through a constructor, or method, or property.

and finally:

var controller = container.Resolve<ManagementController>();

To instantiate the ManagementController and TenantStore objects, you must invoke the Resolve method.

This is one example they give. Howeever, soon after they give another example that seems completely different from this one.

container.RegisterType<ISurveyStore, SurveyStore>();

Here, the register type method is telling the container to instantiate a SurveyStore object when it instantiates an object that requires an injection of an ISurveyStore instance through a constructor, or method, or property.

It is the Resolve() method that confuses me:

var surveyStore = container.Resolve<ISurveyStore>();

In the first example, resolving meant that an object would be instantiated (the ManagementController class), and that a TentantStore instance implementing the ITenantStore interface would be passed to the ManagementController. However, here, instead of a concrete class being "resolved", it is ISurveyStore being resolved. What does this mean? A ISurveyStore instance can't be instantiated because it is an interface, so what is the concrete SurveyStore object being passed into? Does this look to be some sort of mistake? The two examples seem similar in terms of they both RegisterType() and Resolve(), but the actual thing that is being resolved seems completely different in the second example and makes no sense when comparing it to the first.

The example is not an error. The Resolve method is typically used to resolve instances that are registered in the container. So the first example is actually a shortend version (making use of some of Unity's abilities) of the following:

container.RegisterType<ISurveyStore, SurveyStore>();
container.RegisterType<ManagementController, ManagementController>();

container.Resolve<ManagementController>();

So here we register two types, namely ServeyStore and ManagementController . The ServeyStore is mapped to the IServeStore interface, while the ManagementController is mapped to itself. This means, in case you ask for a ManagementController , you'll get a ManagementController .

So typically you register everything you want the container to create for you, and the idea behind Dependency Injection is that you only resolve the root types and that you let the container build up the complete graph of underlying objects for you.

Unity however allows concrete types to be resolved, even though they are not registered. It is typically a good idea to register those types anyway, but that's a different discussion. So the example show cases a few different aspects of Unity: the possibility to make mappings between types and the possibility to resolve concrete classes, even though they might not have been registered.

Unlike the ManagementController , the only way for unity to be able to resolve a ISurveyStory is when it actually knows how to map that to a concrete type, since obviously it is not able to create an interface.

You stated very well what happens in the first example:

In the first example, resolving meant that an object would be instantiated (the ManagementController class), and that a TentantStore instance implementing the ITenantStore interface would be passed to the ManagementController.

The only difference in the second example if you are resolving an interface type. But Unity knows how to resolve it just the same - because you explicitly told it how to. It'll return you an ISurveyStore type, and the underlying object will be SurveyStore , just as if you had done:

ISurveyStore store = new SurveyStore();

what is the concrete SurveyStore object being passed into?

You are resolving it directly, it's not being passed into anything. Unity is smart, you can resolve nested types no matter how deep (as long as it knows how). Here you just happen to be requesting a type directly, that has no dependencies. In the same way, given the first example, you could do:

var tenantStore = container.Resolve<ITenantStore>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM