我正在尝试将依赖项注入共享布局视图页面,以避免在使用该布局的每个视图中执行此操作。
我已经按照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派生的。
答案 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");
将依赖关系注入部分页面。