我想向我的控制器注入一个记录器,我需要将扩展信息传递给记录器的构造函数。为了达到我使用RegisterWithContext的目的
container.RegisterWithContext<Common.Logging.ILogger>(context =>
{
if (context.ServiceType == null && !container.IsVerifying())
{
throw new InvalidOperationException(
"Can't request ILogger directly from container, " +
"it must be injected as a dependency.");
}
return new Common.Logging.NLogLogger(context.ImplementationType.FullName);
});RegisterWithContext扩展方法显式地将提供的委托注册为Transient。
我需要在碰巧是单例的服务中注入相同的Logger (Common.Logging.NLogLogger)。
在升级到SimpleInjector之前,事情似乎像预期的那样正常工作,container.Verify()对整个配置非常满意。
升级之后,验证器返回几个错误:
生活方式失配的SearchEngineIndexerService (Singleton)依赖于ILogger (瞬态)。生活方式失配的MembershipService (网络请求)依赖于ILogger (瞬态)。
这是有道理的。我能理解为什么会发生这种情况,为什么应该避免这种情况。
我试图避免“我是否登录太多”综合症,但实际上,我真的需要在几个服务中进行一些登录。
我尝试使用RegisterConditional根据某些条件注册不同的记录器,但是,当然,现在所有的记录器都应该注册为有条件的,否则我会得到这样的异常:
类型ILogger已经注册为无条件注册。对于非泛型类型,条件注册和无条件注册不能混合。
什么是将记录器注册为临时控制器的最佳方法,以及将另一个记录器注册为单例服务的最佳方法?
发布于 2015-10-05 16:32:25
您现在看到这个异常的原因是,v3.0.6修复了一些臭虫,它阻止了生活方式错配警告在某些情况下出现。
最好忽略RegisterWithContext扩展方法,因为它已经被v3中的RegisterConditional方法所取代。然而,RegisterConditional只允许注册类型,而不允许委托,因为委托允许您根据运行时决策进行决策,但是在对象图解析期间做出运行时决策是错误的做法。
因此,最好定义一个代理记录器类,它允许将调用转发到真正的记录器。例如:
public sealed class Logger<T> : ILogger
{
private static readonly ILogger logger =
new Common.Logging.NLogLogger(typeof(T).FullName);
// Implement ILogger methods here
void ILogger.Log(string message) {
// Delegate to real logger
logger.Log(message);
}
}这一实现可登记如下:
container.RegisterConditional(typeof(ILogger),
c => typeof(Logger<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);文档更详细地描述了这一点。
https://stackoverflow.com/questions/32952701
复制相似问题