2016-12-15 87 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