Autofac可以将依赖项注入布局视图文件吗?

时间:2012-07-21 15:46:23

标签: asp.net-mvc dependency-injection asp.net-mvc-4 autofac

我正在尝试将依赖项注入共享布局视图页面,以避免在使用该布局的每个视图中执行此操作。

我已经按照wiki中的guidance注入视图中的依赖项,但该属性始终为null。

Autofac可以将属性注入到作为布局文件的自定义视图页面吗?

这是我的设置。 CustomViewPage

namespace MyApp
{
    using System.Web.Mvc;

    public abstract class CustomViewPage : WebViewPage
    {
        public IHelper Helper { get; set; }
    }
}

〜/查看/共享/ _Layout.cshtml

@inherits MyApp.CustomViewPage
<!DOCTYPE html>
<html>
...
@if(this.Helper.HasFoo()){@Html.ActionLink("Bar")}

全球注册......

builder.RegisterType<Helper>().AsImplementedInterfaces();
builder.RegisterModelBinderProvider();
builder.RegisterFilterProvider();
builder.RegisterModule(new AutofacWebTypesModule());
builder.RegisterSource(new ViewRegistrationSource());
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

使用布局的“子”视图不是从CustomViewPage派生的。

5 个答案:

答案 0 :(得分:16)

大多数解决方案只是DependencyResolver.Current.GetService调用的包装器,所以直接从布局中调用它可能更容易:

@{
    var helper = DependencyResolver.Current.GetService<IHelper>();
}
...
@if (helper.HasFoo()) { @Html.ActionLink("Bar") }
...

这种方式也有助于使页面模型更具SRP,因为可以避免混合服务例程/模型和业务模式。

答案 1 :(得分:0)

不仅仅是AutoFac,你不能在布局中实现DI。您可能需要在CustomViewPage中引用IOC容器来解析依赖关系。

除非需要重新,否则请避免观看DI(仅限我的意见)。

从我的观点来看,我没有看到太多的好处。我想你不打算为基本视图页面类编写单元测试吗?除非有任何特殊原因要避免它。而不是依赖于容器,最好具有与具体实现的依赖关系。

答案 2 :(得分:0)

这是一个可以解决大多数DI框架的小工作。

首先调整一下CustomPageView:

public abstract class CustomViewPage : WebViewPage
{
    public IHelper Helper { 
        get { return ViewData[Helper.ViewDataKey] as IHelper; }    
    }

}

现在需要将依赖性放入ViewData中,引入一个属性来执行此操作:

public sealed class HelperAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var viewResult = filterContext.Result as ViewResult;
        if (viewResult != null)
            viewResult.ViewData.Add(Helper.ViewDataKey, GetHelperFromIoC());

        base.OnResultExecuting(filterContext);
    }
}

在您的操作方法或控制器上:

[Helper]
public ActionResult Index()
{
    return View();
}

在您看来,您现在应该能够按预期使用您的助手:

 @Helper.HelloWorld()

有关原始帖子的信息,请参阅this blog

答案 3 :(得分:0)

对于没有参数的结果,您不需要扩展WebViewPage来传递数据。 我会这样解决: 1.声明一个派生自ActionFilter的HelperActionFilter类,通过属性middleware将服务注入其中 2.内部HelperActionFilter.OnActionExecuting设置ViewBag.HasFoo在布局中检查它。

答案 4 :(得分:0)

只需创建部分页面并将其插入布局页面:

@Html.Partial("_MyPartialPage");

将依赖关系注入部分页面。