3

I'm building a very simple set of controllers that I would like to inject dependencies into.

My Web Api project is using .net 4.5.1 (vs2015) and I am using Unity for dependency injection (really really new to Unity).

Here's what I've done:

  1. New Project > ASP.Net web appliction > Web Api Project (no auth)
  2. Tools > Nuget Package Manager > Manage Packages for solution... Search for "Unity.MVC" and install package.
  3. I created the following interface and classes:

    public interface IExample
    {
        void DoWork();
    }
    
    public class ServiceA : IExample
    {
        public void DoWork()
        {
            Console.Write("A");
        }
    }
    
    public class ServiceB : IExample
    {
        public void DoWork()
        {
            Console.Write("B");
        }
    }
    

In my simple controller, I implemented this:

    public class HomeController : Controller
    {
        IExample instance;

        public HomeController(IExample injected)
        {
            instance = injected;
        }

        public ActionResult Index()
        {
            ViewBag.Title = "Home Page";

            return View();
        }
    }

I have these two newly added files from Unity:

enter image description here

I add the following code to the UnityConfig.cs:

    public static void RegisterTypes(IUnityContainer container)
    {
        // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
        // container.LoadConfiguration();

        // TODO: Register your types here
        //container.RegisterType<IProductRepository, ProductRepository>();

        container.RegisterType<IExample, ServiceA>();
    }

So far - ALL GOOD! I get the DI into the view as expected. Now I want to do the same for my web api controller, like so:

Run - and get this error:

An error occurred when trying to create a controller of type 'ItemController'. Make sure that the controller has a parameterless public constructor.

What have I done wrong? Full exception:

{
   "Message": "An error has occurred.",
   "ExceptionMessage": "An error occurred when trying to create a controller of type 'ItemController'. Make sure that the controller has a parameterless public constructor.",
   "ExceptionType": "System.InvalidOperationException",
   "StackTrace": "   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n   at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()",
   "InnerException":    {
      "Message": "An error has occurred.",
      "ExceptionMessage": "Type 'WebApplication2.Controllers.ItemController' does not have a default constructor",
      "ExceptionType": "System.ArgumentException",
      "StackTrace": "   at System.Linq.Expressions.Expression.New(Type type)\r\n   at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"
   }
}

Thanks in advance!

4
  • 1
    For some reason your edit is marked as committed by anonymous user and it doesn't show up unless approved by one more user. Commented Nov 9, 2015 at 19:50
  • 1
    According to your (still proposed) update, you only installed Unity.Mvc which takes care of integration with MVC's DependecyResolver. For WebApi, you'll have to install the Unity.WebAPI package: nuget.org/packages/Unity.WebAPI Commented Nov 9, 2015 at 19:53
  • 1
    Show your WebApiConfig.cs and UnityMvcActivator.cs along with any new file that the latest package installation has added. Commented Nov 9, 2015 at 20:19
  • This actually worked - I had to put the registration of the type code back in when I downloaded the new package! Great!!!! Thanks! :-)))) Commented Nov 9, 2015 at 20:22

2 Answers 2

4

The ControllerActivator cannot instantiate your HomeController because its constructor is not marked as public (hence it's actually private).

When you are not providing any constructor at all, the compiler automatically creates a public one for you, but since you are providing one (that is not public) you're ending up with no public constructor.

Try this:

public HomeController(IExample injected)
{
    instance = injected;
}

Update:

As per your edit, for integrating Unity with API controllers, you'll have to install the Unity.WebAPI package as well.

More on WebAPI inegration: http://www.asp.net/web-api/overview/advanced/dependency-injection

Sign up to request clarification or add additional context in comments.

1 Comment

I had referenced the wrong Unity package - now using the Unity.WebAPI package for the MVC Web API project. Thanks!!
-1

For using Dependency Injection with unity in web API use below steps.

  1. Install Unity package in your Web API Project. Go to Package manager console paste below command for install Unity

      Install-Package Unity.WebAPI -Version 5.3.0
    
  2. After installing Unity, In the APP_Start folder of Web API, one file added named as UnitConfig.cs, register your service interface and service logic class in that file.

     public static class UnityConfig
      {
        public static void RegisterComponents()
         {
           var container = BuildUnityContainer();
           GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
         }
       private static IUnityContainer BuildUnityContainer()
        {
          var container = new UnityContainer();                    
          container.RegisterType<ICategoryService, CategoryService> ().RegisterType<UnitOfWork>(new HierarchicalLifetimeManager());
          return container;
         }  
      }
    
  3. Register above RegisterComponents() mehod in Application_Start() mehod of Global.asax file of Web API

       protected void Application_Start()
       {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        UnityConfig.RegisterComponents();
       }
    
  4. The last step is to inject service interface into the web AIP controller constructor.

      public CategoryController(ICategoryService Iinject)
      {
        this._categoryServices= Iinject;
      }
    

1 Comment

.RegisterType<UnitOfWork> in this block UnitOfWork Not getting. reference issue any idea about this

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.