【问题标题】:Castle Windsor won't inject Logger in a property!Castle Windsor 不会在属性中注入 Logger!
【发布时间】:2011-08-17 20:17:56
【问题描述】:

我尝试在我的服务类的 ILogger 属性中注入 log4net,但该属性始终为 NULL!

我看过这个话题,但对我没有帮助!

How can I get Castle Windsor to automatically inject a property?

这是 Program.cs

 CastleContainer.Instance
        .Install(
          new RepositoriesInstaller(),
          new PersistenceInstaller(),
          new LoggerInstaller(),
          new FormInstaller(),
          new ServiceInstaller()

          );

        FrmStart form1 = CastleContainer.Resolve<FrmStart>(new {Id="666" });

我使用 log4net.config 外部文件,这是我的安装程序:

public class LoggerInstaller : IWindsorInstaller
{
    #region IWindsorInstaller Members

    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
         container.AddFacility("logging", new LoggingFacility(LoggerImplementation.Log4net, "log4net.config"));
    }

    #endregion
}

这是包含我希望 Windsor 注入的属性的类:

public partial class FrmStart : Form
{
    private EventService EventService;

    private ILogger logger = NullLogger.Instance;
    public ILogger Logger
    {
        get { return logger; }
        set { logger = value; }
    }

    public FrmStart(EventService eventService, string Id)
        : this()
    {

        Logger.Debug("xxx");

        this.EventService = eventService;
        this.id = Id;
    }

请注意,构造函数中的“eventService”和“Id”是正确注入的! 如果我尝试在构造函数中注入 Logger,它会起作用,并且我有 Logger 对象: {log4net.Repository.Hierarchy.DefaultLoggerFactory+LoggerImpl}! :-(

我尝试为 EventService 创建一个公共属性,Windsor 可以正确注入它!所以我认为问题只与 ILogger 接口有关。

我在这里准备了一个简单的完整代码示例:

using Castle.Core.Logging;
using Castle.Facilities.Logging;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;

namespace IocTest
{


public class LoggerInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
         container.AddFacility("logger", new LoggingFacility(LoggerImplementation.Log4net, "log4net.config"));
    }
}
public class LogicInstaller : IWindsorInstaller
{
     public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(AllTypes.FromThisAssembly()
                            .Pick()
                            .If(t => t.Name.StartsWith("Logic"))
                            .Configure((c => c.LifeStyle.Transient)));
    }
}

class Program
{
    static void Main(string[] args)
    {
        IWindsorContainer container = new WindsorContainer();

        container.Install(
        new LoggerInstaller(),
          new LogicInstaller()
          );


        LogicClass1 logic1 = container.Resolve<LogicClass1>();
        LogicClass2 logic2 = container.Resolve<LogicClass2>();
    }
}

public class LogicClass1
{
    private ILogger logger = NullLogger.Instance;
    public ILogger Logger
    {
        get { return logger; }
        set { logger = value; }
    }

    public LogicClass1()
    {
        logger.Debug("Here logger is NullLogger!");
    }
}

public class LogicClass2
{
    public LogicClass2(ILogger logger)
    {
        logger.Debug("Here logger is properly injected!");
    }
}
}

怎么了?

【问题讨论】:

  • 为什么不在构造函数中注入ILogger
  • 遵循最佳实践:castleproject.org/container/facilities/trunk/logging/index.html 我希望 Logger 是可选的,最重要的是我想知道为什么它不会将它注入到属性中!
  • 您是否将安装程序安装到容器中?你是从容器中解析FrmStart 吗?
  • 是的!我用安装代码编辑了主帖。
  • 运气好吗?我有同样的问题。没有交易破坏者只是好奇......

标签: c# inversion-of-control log4net castle-windsor


【解决方案1】:

问题出在你检查的地方:

 public ILogger Logger
    {
        get { return logger; }
        set { logger = value; }
    }

    public LogicClass1()
    {
        logger.Debug("Here logger is NullLogger!");
    }

在构造函数运行之后之后才会发生属性注入,因此检查构造函数中的属性值永远不会显示您期望的值

【讨论】:

    【解决方案2】:

    我遇到了同样的问题。一直是null

    我设法通过在构造函数中注入记录器来解决这个问题:

    public ILogger logger;
    
    public MyController(ILogger logger)
    {
        this.logger = logger;
    
        logger.Info("Something");
    }
    

    【讨论】:

    • 我刚遇到同样的问题,属性注入始终为空,但构造函数注入器工作正常...我的一个应用程序使用 ILogger 的属性注入没有问题,而另一个不起作用;这两个应用程序都在使用 ABP 和使用 log4net 进行城堡日志记录 - 我只是想不通......
    【解决方案3】:

    您还可以使用以下方法初始化您的 Logger:

    public ILogger Logger { get; set; }
    
    public MyController()
    {
         Logger = NullLogger.Instance;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多