Unity:无法从不同的程序集注册类型

时间:2012-06-12 06:25:20

标签: c# asp.net-mvc dependency-injection unity-container

我正在尝试在我的MVC应用程序中实现Dependency injection。我正在使用Unity.Mvc3.dll用于IoC。我只是想知道Unity如何不能从另一个程序集中注册类型。这是代码:

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;
        }
    }
}

MVC控制器中的用法:

[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始终为空。

以下是PlayerService

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();
    }
}

这是完整的错误消息

  

依赖项的解析失败,type =“System.Web.Mvc.IControllerFactory”,name =“(none)”。
  在解决时发生例外情况。
  异常是:InvalidOperationException - 当前类型System.Web.Mvc.IControllerFactory是一个接口,无法构造。你错过了类型映射吗?

4 个答案:

答案 0 :(得分:7)

您正在隐藏catch { return null; }的所有异常,尝试将其删除,并查看解析时抛出的异常。我认为PlayerService构造函数中会抛出异常。

修改

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

  

当MVC应用程序第一次启动时,依赖项   按以下顺序使用以下类型调用解析程序:

     
      
  • IControllerFactory
  •   
  • IControllerActivator
  •   
  • 的HomeController
  •   
     

如果没有实现解析器,则返回null   注册后你可能会看到类似于:

的错误      

当前类型System.Web.Mvc.IControllerFactory是一个接口   并且无法构建

答案 1 :(得分:6)

默认情况下,unity选择具有最多参数的构造函数,因此我认为它将尝试使用dbContext参数的第二个构造函数,它无法解析。如果使用属性[InjectionConstructor]标记默认构造函数,那么希望这将解决您的问题

答案 2 :(得分:2)

您违反了IDependencyResolver的合同。对于无法解析的类型,它应返回null。 Unity的问题在于它试图构建它可以找到的所有类,无论它们是否在容器中注册。

因此无法建立某个类。

nuget中还有一个Unity.Mvc3个包。

答案 3 :(得分:0)

当前类型(EX-DI.IBLL.IEmployee)是一个接口,无法构造。你错过了类型映射吗?

答案只需在Unity.config.cs添加以下内容

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));
        }
    }