Unity Object Constructor Question

Aug 2, 2014 at 2:55 PM
Hi,

I'm just beginning to understand how to use Unity, but I'm not really understanding how constructor injection works. I want to register HttpClient with the container so that a new instance is created whenever it is resolved. But for each instance that's resolved I want to pass an instance of HttpBaseProtocolFilter to the constructor, with the AutomaticDecompression property set to true.

Here's the non unity code:-
HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();
filter.AutomaticDecompression = true;
HttpClient httpClient = new HttpClient(filter);
I'm struggling to understand how to do this in Unity?

Thanks
Russ
Aug 3, 2014 at 12:35 AM
Constructor Injection is just a fancy way of saying that the (Unity) container passes in arguments to the constructor. So, the first thing you would (/could) try would be to just naively resolve the class that you want from the container:
IUnityContainer container = new UnityContainer();
var client = container.Resolve<HttpClient>();

If you do this you will get an exception:

Resolution of the dependency failed, type = "Windows.Web.Http.HttpClient", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, Windows.Web.Http.Filters.IHttpFilter, is an interface and cannot be constructed. Are you missing a type mapping?

Well, that wasn't what we wanted! Also, the exception could be confusing because we asked Unity to give us an HttpClient but it's complaining about an IHttpFilter.

What is happening is that when you ask Unity to resolve HttpClient it needs to choose a constructor to invoke. By default Unity will use the constructor with the most parameters. In this case HttpClient has a constructor which accepts an IHttpFilter. What Unity is saying is that it doesn't know how to create an object that implements an IHttpFilter interface.

The constructor Unity chose is the one you wanted (since you want to inject an IHttpFilter) so we can use that constructor.

The next step is tell Unity how to construct an IHttpFilter:
IUnityContainer container = new UnityContainer();
container.RegisterType<IHttpFilter, HttpBaseProtocolFilter>();
var client = container.Resolve<HttpClient>();

Now Unity knows that when it needs an IHttpFilter to return an HttpBaseProtocolFilter. The default value for AutomaticDecompression is true so you are done.

But what would we do if the default value was false (or if we wanted to set the value to false)? In that case we could use an InjectionProperty to tell Unity to set the property value:
IUnityContainer container = new UnityContainer();
container.RegisterType<IHttpFilter, HttpBaseProtocolFilter>(new InjectionProperty("AutomaticDecompression", false));
var client = container.Resolve<HttpClient>();

You might want to read the Developer's Guide to Dependency Injection Using Unity.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Aug 6, 2014 at 7:10 PM
Randy thanks so much for this!

It worked perfectly and clarified much muddy water!

Thank you again!

Russ