当通过简单注入器构造时,向Logger添加SessionId

本文关键字:Logger 添加 SessionId 简单 注入器 | 更新日期: 2023-09-27 18:04:52

使用c# MVC和Simple Injector

My Logger被这样创建;

container.Register<ILogger>(() => new Logger("MVC Logging Startup"), Lifestyle.Scoped);

这被完美地传递给所有需要它的类。但是,我需要一种方法来标识发生在用户身上的事件。在我看来,实现它的最简单的方法是通过将sessionId传递到记录器,这样每次使用记录器的类,无论是控制器,业务类还是数据处理类,我都可以跟踪单个会话事件。

container.Register<ILogger>(() => new Logger(this.Session.SessionId), Lifestyle.Scoped);

在应用程序启动时不能工作,因为HttpContextnull。我能看到做到这一点的唯一方法是每次调用控制器构造函数时手动将sessionId设置为日志记录器。但这似乎是违反直觉的。那么,我如何将当前的SessionId(或唯一标识符)传递到我的Logger中呢?

当通过简单注入器构造时,向Logger添加SessionId

您遇到的问题是由于您将运行时数据注入到组件中造成的。这是一个反模式,应该避免,因为:

它会导致歧义,使组合根具有额外的责任,并且使验证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);