Property injection into custom WebViewPage using Autofac

微笑、不失礼 提交于 2019-12-06 06:51:00

The problem stems from the fact that InitHelpers is being called (via Layout.Execute()) BEFORE Application_Start is called

I don't think that something is called before Application_Start. I cannot reproduce your problem.

Here are the steps I did and which worked perfectly fine:

  1. Create a new ASP.NET MVC 3 application using the Internet Template
  2. Install the Autofac.Mvc3 NuGet
  3. Define a dummy interface:

    public interface IDataReader
    {
    
    }
    
  4. And a dummy implementation:

    public class DataReader : IDataReader
    {
    
    }
    
  5. Define a custom helper:

    public class OuHelper<TModel> where TModel : class
    {
        private readonly IDataReader dataReader;
        public OuHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, IDataReader dataReader)
            : this(viewContext, viewDataContainer, RouteTable.Routes, dataReader)
        {
        }
    
        public OuHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection, IDataReader dataReader)
        {
            ViewContext = viewContext;
            ViewData = new ViewDataDictionary<TModel>(viewDataContainer.ViewData);
            this.dataReader = dataReader;
        }
    
        public ViewDataDictionary<TModel> ViewData { get; private set; }
    
        public ViewContext ViewContext { get; private set; }
    
        public IDataReader DataReader
        {
            get { return this.dataReader; }
        }
    
    }
    
  6. Define a custom WebViewPage using this helper:

    public abstract class OuBaseViewPage<TModel> : WebViewPage<TModel> where TModel : class
    {
        public OuHelper<TModel> Ou { get; set; }
    
        public override void InitHelpers()
        {
            base.InitHelpers();
            var dataReader = DependencyResolver.Current.GetService<IDataReader>();
            Ou = new OuHelper<TModel>(ViewContext, this, dataReader);
        }
    }
    
  7. Replace the default view page with the custom one in ~/Views/web.config:

    <pages pageBaseType="MvcApplication1.OuBaseViewPage">
    
  8. Configure your container in Application_Start:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    
        var builder = new ContainerBuilder();
        builder.RegisterControllers(typeof(MvcApplication).Assembly);
        builder.RegisterType<DataReader>().As<IDataReader>();
        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    }
    
  9. Now you could happily use the custom helper in all views including the _Layout without any problems:

    @Ou.DataReader.GetType()
    

Of course in this example I have just exposed the IDataReader dependency as a public property to illustrate you that it will always be injected and it will never be null. In your particular code you could of course use only the private readonly field inside the helper to achieve your task.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!