通过Simple Injector构建时,将SessionId添加到Logger

时间:2016-08-31 14:20:25

标签: c# asp.net-mvc dependency-injection simple-injector

使用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);

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

1 个答案:

答案 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);