[英]StructureMap injection per web request
I have an ASP.NET Web Api 2 REST service with several controllers. 我有一个带有多个控制器的ASP.NET Web Api 2 REST服务。 Each one of these controllers' constructor has got an ILogger argument which I have to inject with StructureMap.
这些控制器的构造函数中的每一个都有一个ILogger参数,我必须将其与StructureMap一起插入。 Is it possibile to instantiate an ILogger per request, in order to get client's specific informations - such as the IP address - and thus save the log file to a specific path?
是否可以为每个请求实例化一个ILogger,以获取客户端的特定信息(例如IP地址),然后将日志文件保存到特定路径?
This is the code I'm trying to run in the DefaultRegistry, but HttpContext is always null. 这是我试图在DefaultRegistry中运行的代码,但是HttpContext始终为null。 Where am I wrong?
我哪里错了?
For<ILogger>()
.Use(() => new TextFileLogger(
HttpContext.Current.Request.UserHostAddress +
DirectorySeparatorChar + "log.txt"));
I'm not an expert on StructureMap but I understand the problem. 我不是StructureMap的专家,但我了解这个问题。 The problem you have is that you use runtime data to build up your object graph.
您遇到的问题是您使用运行时数据来构建对象图。 And injecting runtime data is an anti-pattern .
注入运行时数据是一种反模式 。
The simple solution here is not to use the HttpContext
directly in your composition root but to create a provider which you can use to determine the path in the FileLogger
. 这里的简单解决方案不是在组合根目录中直接使用
HttpContext
,而是创建一个可用于确定FileLogger
路径的提供FileLogger
。 In that case both the FileLogger
as this new provider can become singleton, which is far easier to work with and understand. 在这种情况下,作为该新提供程序的
FileLogger
都可以成为单例,这更容易使用和理解。
A provider could be as simple as (c#6 syntax): 提供程序可以很简单(c#6语法):
public class HttpLogfileProvider : ILogFileProvider
{
public string PathToLogfile =>
Path.Combine(HttpContext.Current.Request.UserHostAddress, "log.txt");
}
Your FileLogger
can use this provider as follows: 您的
FileLogger
可以按以下方式使用此提供程序:
public class FileLogger : ILogger
{
private readonly ILogFileProvider logFileProvider;
public FileLogger(ILogFileProvider logFileProvider)
{
this.logFileProvider = logFileProvider;
}
public void Log(string message)
{
using (var writer = new StreamWriter(this.currentLogFile))
{
writer.WriteLine(message);
}
}
private string currentLogFile =>
this.logFileProvider.PathToLogFile;
}
I'm not an structuremap user but I think the registration should be: 我不是结构图用户,但我认为注册应该是:
For<ILogFileProvider>.Use<HttpLogfileProvider>.Singleton;
For<ILogger>.Use<FileLogger>.Singleton;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.