Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Web API and Unity for dependency injection

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!

like image 286
Rob McCabe Avatar asked Mar 10 '26 06:03

Rob McCabe


1 Answers

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

like image 138
haim770 Avatar answered Mar 12 '26 18:03

haim770



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!