使用c#MVC和Simple Injector。
我的记录器是这样创建的;
container.Register<ILogger>(() => new Logger("MVC Logging Startup"), Lifestyle.Scoped);
这将被传递到完全需要它的所有类中。但是,我需要一种识别发生在用户身上的事件的方法。在我看来,最简单的实现方法是将sessionId传递给记录器,这样每次使用记录器的类,无论是控制器,业务类还是数据处理类,我都可以跟踪单个会话事件。
container.Register<ILogger>(() => new Logger(this.Session.SessionId), Lifestyle.Scoped);
将无法在应用程序启动时HttpContext
为null
。我能看到的唯一方法是每次调用控制器构造函数时手动将sessionId
设置到记录器中。但这似乎是违反直觉的。那么如何将当前SessionId
(或唯一标识符)传递到我的记录器中。
答案 0 :(得分:2)
您遇到的问题是由injecting runtime data into your components造成的。这是一种反模式,应该加以防止,因为:
它会导致含糊不清,使组合根变得更加复杂,并且使得验证DI配置的正确性变得非常困难。
解决方案是:
让运行时数据流过构造对象图的方法调用。
链接文章还描述了问题的解决方案,即提取抽象背后的运行时值。例如:
public interface IUserContext
{
int SessionId { get; }
}
这可以实现如下:
class HttpSessionUserContext : IUserContext
{
public int SessionId => (int)HttpContext.Current.SessionId;
}
现在您可以按如下方式完成注册:
var userContext = new HttpSessionUserContext();
container.Register<ILogger>(() => new Logger("MVC Logging Startup", userContext),
Lifestyle.Scoped);