Castle Windsor will not own Logger!

I am trying to inject log4net into the ILogger property of my service class, but the property is always NULL!

I saw this topic, but it does not help me!

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

this is program.cs

CastleContainer.Instance .Install( new RepositoriesInstaller(), new PersistenceInstaller(), new LoggerInstaller(), new FormInstaller(), new ServiceInstaller() ); FrmStart form1 = CastleContainer.Resolve<FrmStart>(new {Id="666" }); 

I am using an external log4net.config file and this is my installer:

 public class LoggerInstaller : IWindsorInstaller { #region IWindsorInstaller Members public void Install(IWindsorContainer container, IConfigurationStore store) { container.AddFacility("logging", new LoggingFacility(LoggerImplementation.Log4net, "log4net.config")); } #endregion } 

This class contains the property that I want Windsor to introduce:

 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; } 

Please note that "eventService" and "Id" in the constructor are correctly entered! If I try to inject Logger into the constructor, it works, and I have a Logger object: {Log4net.Repository.Hierarchy.DefaultLoggerFactory + LoggerImpl} !: - (

I tried to create a public EventService property and Windsor can enter it correctly! Therefore, I think the problem is only related to the ILogger interface.

I prepared a simple example with full code:

 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!"); } } } 

What's wrong?

+6
source share
3 answers

The problem is where you check it:

  public ILogger Logger { get { return logger; } set { logger = value; } } public LogicClass1() { logger.Debug("Here logger is NullLogger!"); } 

Property entry will not occur until the constructor is started, so checking the value of the property in the constructor will never display the expected value

+13
source

I had the same problem. It has always been null .

I managed to solve the problem by entering logger in the constructor as follows:

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

You can also initialize your registrar using:

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

Source: https://habr.com/ru/post/887209/


All Articles