每个 Web 请求的 StructureMap 注入
StructureMap injection per web request
我有一个带有多个控制器的 ASP.NET Web Api 2 REST 服务。这些控制器的每个构造函数都有一个 ILogger 参数,我必须用 StructureMap 注入它。是否可以为每个请求实例化一个 ILogger,以获取客户端的特定信息(例如 IP 地址),从而将日志文件保存到特定路径?
这是我试图 运行 在 DefaultRegistry 中的代码,但 HttpContext 始终为空。我哪里错了?
For<ILogger>()
.Use(() => new TextFileLogger(
HttpContext.Current.Request.UserHostAddress +
DirectorySeparatorChar + "log.txt"));
我不是 StructureMap 方面的专家,但我理解这个问题。您遇到的问题是您使用运行时数据来构建对象图。还有 injecting runtime data is an anti-pattern.
这里的简单解决方案不是直接在组合根中使用 HttpContext
,而是创建一个提供程序,您可以使用它来确定 FileLogger
中的路径。在那种情况下,FileLogger
作为这个新的提供者都可以成为单例,这更容易使用和理解。
提供程序可以像(c#6 语法)一样简单:
public class HttpLogfileProvider : ILogFileProvider
{
public string PathToLogfile =>
Path.Combine(HttpContext.Current.Request.UserHostAddress, "log.txt");
}
您的 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;
}
我不是结构图用户,但我认为注册应该是:
For<ILogFileProvider>.Use<HttpLogfileProvider>.Singleton;
For<ILogger>.Use<FileLogger>.Singleton;
我有一个带有多个控制器的 ASP.NET Web Api 2 REST 服务。这些控制器的每个构造函数都有一个 ILogger 参数,我必须用 StructureMap 注入它。是否可以为每个请求实例化一个 ILogger,以获取客户端的特定信息(例如 IP 地址),从而将日志文件保存到特定路径?
这是我试图 运行 在 DefaultRegistry 中的代码,但 HttpContext 始终为空。我哪里错了?
For<ILogger>()
.Use(() => new TextFileLogger(
HttpContext.Current.Request.UserHostAddress +
DirectorySeparatorChar + "log.txt"));
我不是 StructureMap 方面的专家,但我理解这个问题。您遇到的问题是您使用运行时数据来构建对象图。还有 injecting runtime data is an anti-pattern.
这里的简单解决方案不是直接在组合根中使用 HttpContext
,而是创建一个提供程序,您可以使用它来确定 FileLogger
中的路径。在那种情况下,FileLogger
作为这个新的提供者都可以成为单例,这更容易使用和理解。
提供程序可以像(c#6 语法)一样简单:
public class HttpLogfileProvider : ILogFileProvider
{
public string PathToLogfile =>
Path.Combine(HttpContext.Current.Request.UserHostAddress, "log.txt");
}
您的 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;
}
我不是结构图用户,但我认为注册应该是:
For<ILogFileProvider>.Use<HttpLogfileProvider>.Singleton;
For<ILogger>.Use<FileLogger>.Singleton;