Question

I'm trying to implement Dependency injection in my MVC application. I'm using Unity.Mvc3.dll for IoC. I just wondering how the Unity can't register Types from another assembly. Here's the code:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    var container = new UnityContainer();

    // ok: register type from this assembly
    container.RegisterType<IMessages, Messages>();

    // fail: register type from another assembly (service reference)
    container.RegisterType<IPlayerService, PlayerService>();

    DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}

public class UnityDependencyResolver : IDependencyResolver
{
    private readonly IUnityContainer _container;

    public UnityDependencyResolver(IUnityContainer container)
    {
        this._container = container;
    }

    public object GetService(Type serviceType)
    {
        try
        {
            return _container.Resolve(serviceType);
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return _container.ResolveAll(serviceType);
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}

Usage in the MVC Controller:

[Dependency]
public IPlayerService PlayerService { get; set; }

[Dependency]
public IMessages Messages { get; set; }


public ActionResult Index()
{
    PlayerMessageViewModel vm = new PlayerMessageViewModel();
    vm.Messages = Messages; // success!
    vm.Players = PlayerService.Get(); // fail: null reference exception :PlayerService

    return View(vm);
}

PlayerService is always null while the Messages is OK.

Here is the PlayerService Class

public class PlayerService : IPlayerService
{
    private readonly MyDbEntities _dbContext;

    public PlayerService()
    {
        _dbContext = new MyDbEntities();
    }

    public PlayerService(MyDbEntities dbContext)
    {
        _dbContext = dbContext;
    }


    public IQueryable<Player> Get()
    {
        return _dbContext.Players.AsQueryable();
    }
}

this is the complete Error Message

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

Was it helpful?

Solution

By default unity picks the constructor with the most parameters, so I think it'll be trying to use the second constructor with the dbContext parameter, which it can't resolve. If you mark your default constructor with the attribute [InjectionConstructor] then hopefully that will solve your problem

OTHER TIPS

You are hiding all exceptions with catch { return null; } try to remove it and see what exception is thrown while resolving. I think exception is thrown in PlayerService constructor.

EDIT:

From http://mvchosting.asphostcentral.com/post/ASPNET-MVC-3-Hosting-Problem-in-implementing-IControllerActivator-in-ASPNET-MVC-3.aspx

When an MVC application starts for the first time, the dependency resolver is called with the following types in the following order:

  • IControllerFactory
  • IControllerActivator
  • HomeController

If you did not implement your resolver to return null if a type is not registered then you will probably end up seeing an error similar to:

The current type, System.Web.Mvc.IControllerFactory, is an interface and cannot be constructed

You are violating the contract of IDependencyResolver. It should return null for types which can not be resolved. The problem with Unity is that it tries to build all classes that it can find, no matter if they are registered in the container or not.

Hence a class somewhere can not be built.

There is also a Unity.Mvc3 package available in nuget.

The current type, (EX-DI.IBLL.IEmployee), is an interface and cannot be constructed. Are you missing a type mapping?

Ans - Just in Unity.config.cs add the following thye

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

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

            **container.RegisterType<IEmployee,EmployeeManager>();**
//this could be your interface and the class implementing the interface.

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top