17

我正在尝试将依赖项注入到共享布局视图页面中,以避免在使用该布局的每个视图中都必须这样做。

我已按照 wiki 中的指导将依赖项注入视图,但该属性始终为空。

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

这是我的设置。自定义视图页面

namespace MyApp
{
    using System.Web.Mvc;

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

~/Views/Shared/_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 派生的。

4

5 回答 5

21

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

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

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

于 2014-10-06T19:59:15.467 回答
1

这是一个适用于大多数 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:

 @Helper.HelloWorld()

有关原始帖子,请参阅此博客

于 2014-07-29T01:20:47.520 回答
1

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

@Html.Partial("_MyPartialPage");

依赖项被注入到部分页面中。

于 2016-10-12T13:46:24.897 回答
0

不仅使用 AutoFac,基本上您无法在布局中实现 DI。您可能需要对 IOC 容器的引用CustomViewPage来解决依赖关系。

除非真的需要,否则在视图中避免 DI(只是我的观点)。

从我的角度来看,我没有看到太多好处。我认为您不会为基本视图页面类编写单元测试吗?除非有任何特殊原因,否则请避免。与其依赖于容器,不如依赖于具体的实现。

于 2012-07-22T14:33:36.947 回答
0

对于没有参数的结果,您不需要扩展您的 WebViewPage 以将数据传递到。我会这样解决它: 1. 声明一个派生自 ActionFilter 的类 HelperActionFilter,通过属性http://docs.autofac.org/en/latest/integration/mvc.html向它注入您的服务 2. 在 HelperActionFilter.OnActionExecuting 设置中ViewBag.HasFoo 在布局中检查它。

于 2016-02-25T13:35:28.590 回答