Windsor城堡,依赖注射返回null



可能从一开始我的想法是错误的。

我有一个MVC5项目,我正在尝试在我的网站和EF之间实现一个存储库层(对于半Plicity,这是一个学习项目)。

我有一个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是在我的所有上下文中使用通用存储库,并为我的网站内的不同领域/范围(日志记录,帐户管理等)创建单独的上下文和单独的"第二层",以便我可以使用,如果我可以使用,如果我想要不同的DB实现。

这是温莎的实现:

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为null。为什么?

Logger属性需要为 public

完整的文档在这里,相关细节是:

依赖项的属性注入设计为在创建组件时在组件激活期间完成。默认情况下,通过PropertiesDependenciesModelInspector- IContributeComponentModelConstruction实现来确定使用哪些属性进行注入的责任,该实现使用以下所有标准来确定属性是否代表依赖关系:

  • 有"公共"可访问的设置器
  • 是一个实例属性
  • 如果componentModel.inspectionbehavior设置为propertiesInspectionBehavior.declaredonly,则不继承
  • 没有参数
  • 未用Castle.core.donotwireattribute属性注释

如果属性符合所有这些标准,则为其创建一个依赖模型,然后在激活过程中解决组件依赖关系时解决。

最新更新