【发布时间】:2011-12-01 15:14:20
【问题描述】:
我正在更改我的 Asp.Net MVC3 项目以使用 Autofac 将服务注入到我的控制器中。到目前为止,这非常简单。我的服务都有一个 Telerik OpenAccess db 属性,我通过构造函数(在服务基类中)注入该属性。而且我的控制器都具有用于注入的服务的构造函数属性。
我有一个名为 AuditInfo 的类,它封装了控制器的可审计属性:
public class AuditInfo
{
public string RemoteAddress { get; set; }
public string XForwardedFor { get; set; }
public Guid UserId { get; set; }
public string UserName { get; set; }
}
我的服务类中的 OpenAccess db 属性需要将此类的实例注入其中,以便在各种数据库调用中用作审计信息。
问题在于,这不是一个可以在 Application_Start 实例化的类,因为它的至少两个属性 RemoteAddress 和 XForwardedFor 在 OnActionExecuting 的最早阶段填充,即一旦存在 Request 变量。
因此,我在我的 BaseController 类的 OnActionExecuting 方法中实例化它:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
db.AuditInfo = AuditInfo;
}
public AuditInfo AuditInfo
{
get
{
return new AuditInfo()
{
RemoteAddress = this.Request.ServerVariables["REMOTE_ADDR"],
XForwardedFor = this.Request.ServerVariables["X_FORWARDED_FOR"],
UserId = this.UserId,
UserName = this.UserName
};
}
}
所以 - 我的问题/问题是:
- 我不喜欢在 OnActionExecuting 中直接访问 OpenAccess db 属性。
- 我希望基本上将此 AuditInfo 注入到任何地方的任何 AuditInfo 属性中
- 我认为我不能对 AuditInfo 使用构造函数注入,因为服务依赖于 db - 控制器依赖于服务 - db 依赖于 AuditInfo 但在控制器被实例化并收到其第一个请求之前,AuditInfo 不可用。 => 循环依赖...
如何设置 autofac 以将 AuditInfo 注入到任何将其作为属性的类中?或者有没有更好的方法来回避循环依赖并使用某种形式的 lambda/lazy 构造函数属性?
即使很多请求可能是同一会话的一部分并且没有不同的 IP 地址/用户信息,AuditInfo 是否会在每次请求时都可能不必要地重新初始化?
谢谢
【问题讨论】:
-
我不同意问题/问题 3 - 正如 Steven 指出的,您可以使用
HttpContext.Current。所以AuditInfo不依赖于控制器,所以没有循环依赖,所以你可以根据需要构造函数注入AuditInfo。 -
嗯 - 我认为这是因为建议的解决方案是使用全局静态变量来引用 Request 对象,而不是在 Request 对象自然存在的控制器内部初始化 AuditInfo 对象。我认为服务器变量在发生注入的 Application_Start 中甚至还不存在,因为必须首先调用一个动作,不是吗?
标签: asp.net-mvc-3 dependency-injection inversion-of-control autofac circular-dependency