Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Unity.Resolve know which constructor to use?

Given a class with several constructors - how can I tell Resolve which constructor to use?

Consider the following example class:

public class Foo {     public Foo() { }     public Foo(IBar bar)     {         Bar = bar;     }     public Foo(string name, IBar bar)     {         Bar = bar;         Name = name;     }     public IBar Bar { get; set; }             public string Name { get; set; } } 

If I want to create an object of type Foo using Resolve how will Resolve know which constructor to use? And how can I tell it to use the right one? Let's say I have a container with an IBar registered - will it understand that it should favor the constructor taking IBar? And if I specify a string too - will it use the (string, IBar) constructor?

Foo foo = unityContainer.Resolve<Foo>();  

And please ignore the fact that it would probably be easier if the class just had a single constructor...

like image 940
stiank81 Avatar asked Mar 18 '10 13:03

stiank81


People also ask

What is the use case of resolve with respect to unity?

Unity creates an object of the specified class and automatically injects the dependencies using the resolve() method. We have registered BMW with ICar above. Now, we can instantiate the Driver class using Unity container without using the new keyword as shown below.

What is Unitycontainer C#?

The Unity Container (Unity) is a full featured, extensible dependency injection container. It facilitates building loosely coupled applications and provides developers with the following advantages: Simplified object creation, especially for hierarchical object structures and dependencies.

What is unity registration?

Registration is how you control Unity to do it 'Your' way. When you register a Type , you are instructing Unity to create and initialize an instance of that Type in a very particular way. You also instruct Unity how to deal with the crated instance during its lifetime.

What is Microsoft Unity framework?

Unity is a real-time 3D development platform for building 2D and 3D application, like games and simulations, using . NET and the C# programming language. Unity can target 25+ platforms across mobile, desktop, console, TV, VR, AR, and the web. Unity is FREE to start with and is available for both Windows and macOS.


2 Answers

When a target class contains more than one constructor, Unity will use the one that has the InjectionConstructor attribute applied. If there is more than one constructor, and none carries the InjectionConstructor attribute, Unity will use the constructor with the most parameters. If there is more than one such constructor (more than one of the “longest” with the same number of parameters), Unity will raise an exception.

Taken from link text

like image 148
ozczecho Avatar answered Oct 07 '22 23:10

ozczecho


When you register the type, you can specify which constructor to use like this:

container.RegisterType<Foo>(     new InjectionConstructor(         new ResolvedParameter<IBar>())); 

The above code is from memory, but that's the general principle. In this case I've picked the constructor that takes a single parameter of type IBar.

And please ignore the fact that it would probably be easier if the class just had a single constructor...

I can't ignore this. When it comes to Constructor Injection, ambiguity is a design smell. You are basically saying: I don't really know if I care about this dependency or not.

Sure, Unity is likely to figure it out for you, but then you would be relying on a specific container behavior instead of properly designing your API. Other containers may have a different behavior, so if you ever choose to migrate from Unity to a better container, subtle bugs may occur.

It's much safer to write your code in a DI-friendly, but container-agnostic manner.

like image 31
Mark Seemann Avatar answered Oct 07 '22 21:10

Mark Seemann