Autofac属性注入

t31*_*316 6 dependency-injection circular-dependency inversion-of-control autofac asp.net-mvc-3

我正在改变我的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; }
}
Run Code Online (Sandbox Code Playgroud)

我的服务类中的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
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

所以 - 我的问题是:

  1. 我不喜欢直接进入OnActionExecuting的OpenAccess db属性.
  2. 我希望这个AuditInfo基本上可以在任何地方注入任何AuditInfo属性
  3. 我不认为我可以对AuditInfo使用构造函数注入,因为服务依赖于db - 控制器依赖于服务 - db依赖于AuditInfo但是在实例化控制器并收到第一个请求之前,AuditInfo不可用.=>循环依赖...

我如何设置autofac将AuditInfo注入任何将其作为属性的类?或者是否有更好的方法来回避循环依赖并使用某种形式的lambda/lazy构造函数属性?

即使许多请求可能是同一会话的一部分并且没有不同的IP地址/用户信息,但是在每次请求时可能会不必要地重新初始化AuditInfo吗?

谢谢

def*_*mer 3

事实证明Autofac 的 MVC 集成可以为您解决HttpRequestBase. 所以不需要HttpContext.Current.Request直接引用。

Autofac 的实现在幕后使用。HttpContext.Current这是有效的,因为 MVC 框架HttpContext.Current在您的代码(或 Autofac 的)运行之前设置。因此,不存在循环依赖 - 请求“自然存在”,HttpContext.Current.Request就像在控制器中一样。(这个问题有点解释了如何)

因此,您可以IAuditInfoFactory按照 Steven 的建议执行 an 操作,但如果它让您对不引用静态变量感觉更好,则要求HttpRequestBase在其构造函数中使用 an 而不是 using 。HttpContext.Current

此外,不存在循环依赖,AuditInfo如果需要,您可以构造函数注入:

builder.Register(c => c.Resolve<IAuditInfoFactory>().CreateNew())
    .As<AuditInfo>()
    .InstancePerHttpRequest();
Run Code Online (Sandbox Code Playgroud)