Unity Container is used in Web API/MVC with hierarchical solution architecture to achieve the dependency injection (IOC).
Let us suppose the solution architecture is as in the below image.
The solution contains different layers. In order to achieve the Dependency Injection, let us suppose we configure Unity Container by adding the reference using NuGet Package Manager.
Below is the configuration to map Interfaces with concrete Classes for Unity Container in WebAPIConfig.cs of API Solution.
- public static class WebApiConfig
- {
- public static void Register(HttpConfiguration config)
- {
-
-
- config.SuppressDefaultHostAuthentication();
- config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
-
- RegisterInterfacesWithUnity(config);
-
- config.MapHttpAttributeRoutes();
-
- config.Routes.MapHttpRoute(
- name: "DefaultApi",
- routeTemplate: "api/{controller}/{id}",
- defaults: new { id = RouteParameter.Optional }
- );
- }
-
- public static void RegisterInterfacesWithUnity(HttpConfiguration config)
- {
-
- IUnityContainer container = new UnityContainer();
-
- container.RegisterType<ICustomerManager, CustomerManager>(new HierarchicalLifetimeManager());
- container.RegisterType<ICustomerData, CustomerData>(new HierarchicalLifetimeManager());
-
- config.DependencyResolver = new UnityResolver(container);
- }
- }
Our Services communicate as Controller - BusinessLayer - DataAccessLayer.
In the above image, we register both the layer interfaces, like ICustomerManager, and ICustomerData. Suppose, if the developer missed adding any of the interfaces, then at runtime, we will get an exception saying "An error occurred when trying to create a controller of type 'CustomerController'. Make sure that the controller has a parameterless public constructor."
It is very difficult to understand what’s gone wrong. In order to solve this problem, let us use the test methods to verify whether all the hierarchy interfaces are getting resolved by the Unity Container.
The below snippet shows the test method to verify the container register resolve.
- [TestClass]
- public class VerifyContainerResolving
- {
- [TestMethod]
- public void TestMethod1()
- {
- IUnityContainer container = new UnityContainer();
-
-
- container.RegisterType<ICustomerManager, CustomerManager>(new HierarchicalLifetimeManager());
-
-
-
- container.AddExtension(new Diagnostic());
- foreach (var registration in container.Registrations)
- {
- try
- {
- container.Resolve(registration.RegisteredType, registration.Name);
- }
- catch (ResolutionFailedException ex)
- {
- Assert.Fail(string.Concat(ex.Message, "\n", ex.StackTrace.ToString()));
- }
- }
-
- }
- }
Test method output result.
Let us comment any one of the registries. Then, you can get where exactly it is breaking.
- [TestClass]
- public class VerifyContainerResolving
- {
- [TestMethod]
- public void TestMethod1()
- {
- IUnityContainer container = new UnityContainer();
-
-
- container.RegisterType<ICustomerManager, CustomerManager>(new HierarchicalLifetimeManager());
-
-
-
- container.AddExtension(new Diagnostic());
- foreach (var registration in container.Registrations)
- {
- try
- {
- container.Resolve(registration.RegisteredType, registration.Name);
- }
- catch (ResolutionFailedException ex)
- {
- Assert.Fail(string.Concat(ex.Message, "\n", ex.StackTrace.ToString()));
- }
- }
-
- }
- }
Test method results after commenting one registry map.
By using the above test method logic, we can easily find out the missing register of the interfaces while using Unity Container with WebAPI multilayered architecture.
Please refer to the code sample attached to the articles.