2011-05-03 51 views
6

我嘗試在我的服務類的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 
} 

這是類包含我想要的屬性溫莎注入:

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和溫莎的公共屬性可以適當注入了!所以,我認爲這個問題是隻與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!"); 
    } 
} 
} 

什麼是錯

+0

你爲什麼不injeect了' ILogger'在構造函數中? – Steven 2011-05-17 07:04:21

+0

遵循此最佳做法:http://www.castleproject.org/container/facilities/trunk/logging/index.html 我希望Logger是可選的,最重要的是我想知道爲什麼它不會將它注入到屬性! – danyolgiax 2011-05-17 07:18:15

+0

您是否將安裝程序安裝到容器中?你是從容器中解決'FrmStart'嗎? – 2011-05-17 08:31:46

回答

13

一個問題是,你正在檢查它:

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

    public LogicClass1() 
    { 
     logger.Debug("Here logger is NullLogger!"); 
    } 
不會發生

酒店注射,直到運行構造之後,因此檢查構造函數中的屬性值永遠不會告訴你期待

1

我有同樣的問題的值。它總是null

我設法通過這種方式注入記錄器的構造來解決這個問題:

public ILogger logger; 

public MyController(ILogger logger) 
{ 
    this.logger = logger; 

    logger.Info("Something"); 
} 
0

您還可以通過使用初始化記錄儀:

public ILogger Logger { get; set; } 

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