2012-06-12 54 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)); 
     } 
    } 
相關問題