3
votes

I have ASP.NET MVC5 web application and i also have Web API in the same application. I am uisng Unity (version 4) for DI. I am configuring the Unity container on APP start as below

        public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                UnityConfiguration.Config();
            }
        }

        public class UnityConfiguration()
        {
         public void Config()
         {
                UnityContainer container = new UnityContainer();
                container.RegisterType<IMyService, Myservice>();
                container.RegisterType<IGenericRepository, GenericRepository>();
                container.RegisterType<DbContext, MyEntities>();            
         }
        }

        public class GenericRepository:IGenericRepository
        {
           private DbContext _dbcontext;
           public GenericRepository(DbContext dbcontext)
           {
               _dbcontext = dbcontext;
           }
        }
        public class MyService:IMyService
        {
           private IGenericRepository _repo;
           publi void MyService(IGenericRepository repository)
           {
              _repo = repository;
           }
        }


        public class MyApiController:ApiController
        {
           provate IMyService _service;
           MyApiController(IMyService myservice)
           {
              _service = myservice;
           }

           public IEnumerable<MyModel> GetData()
           {
             var result = _service.GetData();
             return result.ConvertToMyModel();
           }
        }

However when i call the url like

localhost://lookup/getdata

I get error

Type 'LookupController' does not have a default constructor

How do i solve this issue? Do i need to register each controller i create with Unity or Unity automatically registers all MVC controllers?

3
You have to either create your own IControllerFactory and IControllerActivator implementations (and register them in MVC and Web API) or implement your own IDependencyResolver (both frameworks have their own IDependencyResolver abstraction) and register those. - Steven
@steven thanks. However I found there is Unity.MVC5 and Unity.Webapi package avalble..however there is also Unity bootstrapper for ASP.NET MVC...so not sure which one to use - LP13

3 Answers

3
votes

I tend to use the Unity.Mvc-package.

You do not need to register the controllers, but you need to register Unity with WebAPI.

   public class UnityConfiguration()
   {
       public IUnityContainer Config()
       {
            IUnityContainer container = new UnityContainer();
            container.RegisterType<IMyService, Myservice>();
            container.RegisterType<IGenericRepository, GenericRepository>();
            container.RegisterType<DbContext, MyEntities>(); 

            // return the container so it can be used for the dependencyresolver.  
            return container;         
       }
    }

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Your routes...

            // Register Unity with Web API.
            var container = UnityConfiguration.Config();
            config.DependencyResolver = new UnityResolver(container);

            // Maybe some formatters?
        }
    }

You also need a DependencyResolver:

public class UnityResolver : IDependencyResolver
{
    protected IUnityContainer container;

    public UnityResolver(IUnityContainer container)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }
        this.container = container;
    }

    public object GetService(Type serviceType)
    {
        try
        {
            return container.Resolve(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return container.ResolveAll(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return new List<object>();
        }
    }

    public IDependencyScope BeginScope()
    {
        var child = container.CreateChildContainer();
        return new UnityResolver(child);
    }

    public void Dispose()
    {
        container.Dispose();
    }
}

You can also take a look at this similiar question, except for the Owin-part. Unity.WebApi | Make sure that the controller has a parameterless public constructor

2
votes

I had the same error and in my case the problem was, that i forgot to register a dependency that one of the classes, I had registered for dependency injection, injects in the constructor.

In your example, could it be that you inject something into MyEntities that you forgot to Register?

0
votes

Install Nuget Package Unit.WebAP instead of Unity.MVC5 Make sure the correct unity package is installed using nuget

I Installed Unity.MVC5 and was facing similar exception "parameterless constructor"

  public static void RegisterComponents()
    {
        var container = new UnityContainer();

        // register all your components with the container here
        // it is NOT necessary to register your controllers

        // e.g. container.RegisterType<ITestService, TestService>();
        container.RegisterType<ICar, Tesla>();
        GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
    }