Castle Windsor,依赖注入返回null

时间:2016-12-15 11:34:56

标签: c# dependency-injection asp.net-mvc-5 castle-windsor

可能我的想法从一开始就错了。

我有一个MVC5项目,我想在我的网站和EF之间实现一个存储库层(为了简单起见,它是一个学习项目)。

我有一个EF Code First Context和一个Repository类:

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将在我的所有上下文中使用通用存储库,并创建单独的上下文和单独的第二层&#34;对于我网站内的不同区域/范围(日志记录,帐户管理等),如果需要,我可以使用不同的数据库实现。

这是Windsor的实施:

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

1 个答案:

答案 0 :(得分:2)

Logger属性必须为public

完整文档here,相关详细信息为:

  

依赖项的属性注入旨在在创建组件时在组件激活期间完成。默认情况下,通过PropertiesDependenciesModelInspector - IContributeComponentModelConstruction实现来确定用于注入的属性的责任,该实现使用以下所有条件来确定属性是否表示依赖关系:

     
      
  • 公共&#39;可访问的二传手
  •   
  • 是实例属性
  •   
  • 如果ComponentModel.InspectionBehavior设置为PropertiesInspectionBehavior.DeclaredOnly,则不会继承
  •   
  • 没有参数
  •   
  • 未使用Castle.Core.DoNotWireAttribute属性进行注释
  •   
     

如果属性满足所有这些条件,则会为其创建依赖关系模型,然后在激活期间解析组件依赖关系时解析该模型。