【发布时间】: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