2016-12-15 79 views
0

可能我的想法從一開始就是錯誤的。Castle Windsor,依賴注入返回null

我有一個MVC5項目,我正努力在我的網站和EF之間實現一個存儲庫層(對於semplicity來說,這是一個學習項目)。

我有一個EF代碼優先上下文,一個存儲庫類:

public interface IRepository<TDbContext> : IDisposable where TDbContext : class, new() 

public class Repository<TContext> : IRepository<TContext>, IDisposable where TContext : DbContext, new() 

然後,我有一個第二層,其中我實現附加功能:

public interface ILog<TLogContext> : IRepository<TLogContext> where TLogContext : class, new() 

public class Logger<TContext> : Repository<TContext>, ILog<TContext> where TContext : LogContext, new() 

的porpouse是使用通用爲我的所有上下文創建存儲庫,併爲我的網站(日誌記錄,帳戶管理等)中的不同區域/範圍創建單獨的上下文和單獨的「第二層」,以便我可以使用不同的數據庫實現。

這是溫莎實現:

Installer.cs

public class Installer : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     // Controller 
     container.Register(
      Classes.FromThisAssembly().BasedOn<IController>().LifestyleTransient()); 

     // EF, Business 
     container.Register(
      Component.For<IRepository<LogContext>>() 
        .ImplementedBy<Repository<LogContext>>() 
        .LifestylePerWebRequest() 
     ); 

     container.Register(
      Component.For<ILog<LogContext>>() 
        .ImplementedBy<Logger<LogContext>>() 
        .LifestylePerWebRequest() 
     ); 
    } 
} 

ControllerFactory.cs

public class ControllerFactory : DefaultControllerFactory 
{ 
    private readonly IKernel kernel; 

    public ControllerFactory(IKernel kernel) 
    { 
     this.kernel = kernel; 
    } 

    public override void ReleaseController(IController controller) 
    { 
     kernel.ReleaseComponent(controller); 
    } 

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
    { 
     if (controllerType == null) 
     { 
      throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path)); 
     } 

     return (IController)kernel.Resolve(controllerType); 
    } 
} 

而且在Global.asax

protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 

     // Windsor 
     container = new WindsorContainer().Install(FromAssembly.This()); 

     // ContainerFactory loading 
     ControllerBuilder.Current.SetControllerFactory(new ControllerFactory(container.Kernel)); 
    } 

BaseController.cs

public class BaseController : Controller 
{ 
    // Services 
    internal ILog<LogContext> Logger { get; set; } 

    public void Test() 
    { 
     var allEvents = Logger.All<Event>(); 
    } 
} 

而且...... Logger爲空。爲什麼?

回答

2

Logger屬性需要爲public

完整的文檔here,相關的細節是:

地產注入的依賴設計組件被創建時將組件激活期間進行。確定哪些屬性用於注射的責任是默認通過PropertiesDependenciesModelInspector滿足 - 一個IContributeComponentModelConstruction實現它使用下列所有條件,以確定是否一個屬性表示依賴關係:

  • 具有「公共」訪問二傳手
  • 是一個實例屬性
  • 如果ComponentModel.InspectionBehavior設置爲PropertiesInspectionBehavior.DeclaredOnly,是不能繼承
  • 沒有參數
  • 沒有被標註與Castle.Core.DoNotWireAttribute屬性

如果屬性滿足所有這些條件,則會爲其創建依賴關係模型,然後在激活期間解決組件依賴關係時解決此問題。

+0

謝謝!似乎我需要閱讀這部分文檔。 – Nodiink

相關問題