如何创建 HttContext 实例并将其注册到 StructureMap 配置中?
我有一个使用 StructureMap 的 MVC3 Web 项目,我认为这是一个典型的设置,其中控制器调用存储库类,而存储库类负责业务逻辑和数据库操作。
StructureMap 用于向控制器注入适当的存储库。
但最近,我需要一些存储库来记录某些操作以及用户的 IP 地址。
要获取 IP 地址,我正在使用
requestContext.HttpContext.Request.UserHostAddress
现在,我认为将 HttpContext 传递到 repo 类中,然后在 StructureMap 中注册 HTTContext 依赖关系是很聪明的,如下所示:
For<RequestContext>().Use(ctx => HttpContext.Current.Request.RequestContext);
到目前为止,这是可行的,但我还有一个迷你项目,它将使用相同的 repo 功能,但作为控制台应用程序运行(或者可能是 win 服务)。这里的问题是没有 ASP.Net 运行时就没有 HttpContext。我收到一个运行时错误,说 httpContext 为空。
我怎样才能在那里获得一个 HttpContext ?
编辑 Alexei 和 Plymouth 建议的解决方案
谢谢,如果我理解 Alexei 的建议,我应该制作一个如下界面:
interface ILoggingConext
{
public string IPAddress { get; set; }
}
然后有 2 个具体类,其中一个 (A) 接受 HTTPContext,另一个 (B) 可以具有 IPAddress 的默认值
然后在 StructureMap 中,对其进行配置,以便在 HttpContext 不为 null 时使用具体类 a。否则,它将使用 B。
我接近了吗?
解决方案
接受 Alexei 的建议,这是我目前使用的解决方案:
首先声明接口和2个具体类
public interface ILoggingContext
{
string IPAddress { get; set; }
string HostAddress { get; set; }
}
public class HttpLoggingContext : ILoggingContext
{
public string IPAddress { get; set; }
public string HostAddress { get; set; }
//This is the concrete class to use if context is available, so provide a constructor to accept a context and set properties appropriately
public HttpLoggingContext(RequestContext rContext)
{
if (rContext != null && rContext.HttpContext != null && rContext.HttpContext.Request != null)
{
this.IPAddress = rContext.HttpContext.Request.UserHostAddress;
this.HostAddress = rContext.HttpContext.Request.UserHostName;
}
}
}
//No http context, so just set the properties to something that signifies this, using "local" here
public class ConsoleLoggingContext : ILoggingContext
{
public string IPAddress { get; set; }
public string HostAddress { get; set; }
public ConsoleLoggingContext()
{
this.IPAddress = "local";
this.HostAddress = "local";
}
}
然后这里是 StructureMap 注册表类中的配置:
For<ILoggingContext>().ConditionallyUse(o =>
{
o.If(c => HttpContext.Current!=null && HttpContext.Current.Request!=null && HttpContext.Current.Request.RequestContext!=null).ThenIt.Is.ConstructedBy(a=> new HttpLoggingContext(HttpContext.Current.Request.RequestContext));
o.TheDefault.IsThis(new ConsoleLoggingContext());
}
).Named("ConditionalILoggingContext");
如果 HttpContext.Current.Request.RequestContext 不为空,我们使用 HttpLoggingContext。否则我们使用 ConsoleLoggingContext。
我将此标记为解决方案。谢谢您的帮助