I'm trying to inject a dependency into the shared layout view page to avoid having to do it in every view that uses the layout.
I've followed the guidance in the wiki for injecting dependencies into views, but the property is always null.
Can Autofac inject properties into a custom view page that is a layout file?
Here's my setup. CustomViewPage
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")}
Global Registration...
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));
The "child" views that use the layout do NOT derive from the CustomViewPage.
Autofac is an open-source dependency injection (DI) or inversion of control (IoC) container developed on Google Code. Autofac differs from many related technologies in that it sticks as close to bare-metal C# programming as possible.
AutoFac provides better integration for the ASP.NET MVC framework and is developed using Google code. AutoFac manages the dependencies of classes so that the application may be easy to change when it is scaled up in size and complexity.
Most of solutions will be just a wrapper around DependencyResolver.Current.GetService call, so it might be easier to call it directly from layout:
@{
var helper = DependencyResolver.Current.GetService<IHelper>();
}
...
@if (helper.HasFoo()) { @Html.ActionLink("Bar") }
...
Also this way helps to make page model more SRP, because can avoid mixing service routines/models and business ones.
Here is a little work around that will work with most DI frameworks.
First adjust you CustomPageView a little bit:
public abstract class CustomViewPage : WebViewPage
{
public IHelper Helper {
get { return ViewData[Helper.ViewDataKey] as IHelper; }
}
}
Now well need to get the dependancy into your ViewData, introduce an attribute to do this:
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);
}
}
On you action method or controller:
[Helper]
public ActionResult Index()
{
return View();
}
And in your view you should now be able to use your Helper as expected:
@Helper.HelloWorld()
See this blog for the original post.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With