2012-06-12 46 views
7

我试图在我的MVC应用程序中实现Dependency injection。 IoC使用Unity.Mvc3.dll。我只是想知道Unity如何不能从其他程序集注册类型。下面的代码: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(); 
    } 
} 

这是完整的错误消息

分辨率依赖性的失败,类型= “System.Web.Mvc.IControllerFactory”,名字=“(没有)”。
发生异常时:解析时。
异常是:InvalidOperationException - 当前类型System.Web.Mvc.IControllerFactory是一个接口,无法构造。你是否缺少类型映射?

回答

6

默认情况下,统一挑选最参数的构造,所以我认为它会尝试使用第二个构造无线它无法解决的dbContext参数。如果您使用属性[InjectionConstructor]标记默认构造函数,那么希望这可以解决您的问题

+0

会这样做,谢谢 – lincx

+0

包含什么库的InjectionConstructor属性? – lincx

+0

http://msdn.microsoft.com/en-us/library/microsoft.practices.unity.injectionconstructorattribute(v=pandp.20).aspx –

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,是一个接口 并不能构成

+0

它应该打的默认构造函数吗?我不能让调试器进入ctor的断点。 – lincx

+0

是的,'公共PlayerService()' –

+0

我删除空和替换抛出异常,这就是我得到的'当前类型,System.Web.Mvc.IControllerFactory,是一个接口,不能构造。你错过了一个类型映射吗?' – lincx

2

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

因此无法建立某个地方的类。

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

+0

你是否说这方面没有解决办法? – lincx

+0

它实际上最初返回null,但我只是替换throe异常以查看其他海报建议的实际错误。 – lincx

+1

由于'IControllerActivator'在调用任何控制器之前被调用,'throw'隐藏了从一开始就得到的问题。改回到返回null并且记录所有异常(或者在catch块中放置一个断点) – jgauffin

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)); 
     } 
    } 
相关问题