gpt4 book ai didi

asp.net-mvc-3 - 使用 Autofac 将属性注入(inject)自定义 WebViewPage

转载 作者:行者123 更新时间:2023-12-02 05:14:05 28 4
gpt4 key购买 nike

我正在创建一个内部应用程序框架,我们组织中的其他开发团队将使用该框架来构建 MVC 应用程序。作为其中的一部分,我正在为所有 View 创建菜单结构,该结构从配置中读取并根据当前用户的权限进行修改。为了将菜单创建为框架的一部分,我创建了一个带有自定义 HTML Helper 类的自定义 WebViewPage 实现,该类需要依赖 ApplicationDataReader 来构造菜单。

我读过各种解释 MVC 需要 WebViewPage 来拥有无参数构造函数的帖子,因此我需要使用属性注入(inject)。我配置了Autofac MVC3 Integration ,包括注册一个 ViewRegistrationSource。问题是,当依赖属性被访问时,它总是空的。

这是自定义 View 页面和我正在尝试进行的调用的助手:

public abstract class OuBaseViewPage<TModel> : WebViewPage<TModel> where TModel : class
{
public OuHelper<TModel> Ou { get; set; }

public override void InitHelpers()
{
base.InitHelpers();
Ou = new OuHelper<TModel>(ViewContext, this);
}
}

public class OuHelper<TModel> where TModel : class
{
public OuHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
: this(viewContext, viewDataContainer, RouteTable.Routes)
{
}

public OuHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection)
{
ViewContext = viewContext;
ViewData = new ViewDataDictionary<TModel>(viewDataContainer.ViewData);
}

public ViewDataDictionary<TModel> ViewData { get; private set; }

public ViewContext ViewContext { get; private set; }

public IList<BusinessFocusArea> ReadFocusAreas()
{
// this is null - yes, service location, but an isolated instance of...
return DependencyResolver.Current.GetService<IDataReader>().Read();
}
}

问题源于 InitHelpers 在调用 Application_Start 之前被调用(通过 Layout.Execute()),所以没有的依赖项已注册。我知道将逻辑注入(inject) View 不是好的做法, View 应该是愚蠢的,但这是一个应用程序框架,它需要执行某些使用框架的开发人员不能看到的设置步骤。

我可以采用更好的方法吗?

这里有一个类似的问题:Can Autofac inject dependencies into layout view files?

最佳答案

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

我不认为在 Application_Start 之前调用了什么。我无法重现您的问题。

以下是我执行的步骤,效果非常好:

  1. 使用 Internet 模板创建一个新的 ASP.NET MVC 3 应用程序
  2. 安装 Autofac.Mvc3 NuGet
  3. 定义一个虚拟接口(interface):

    public interface IDataReader
    {

    }
  4. 还有一个虚拟实现:

    public class DataReader : IDataReader
    {

    }
  5. 定义自定义助手:

    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. 使用此助手定义自定义 WebViewPage:

    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. ~/Views/web.config 中的自定义页面替换默认 View 页面:

    <pages pageBaseType="MvcApplication1.OuBaseViewPage">
  8. 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. 现在您可以毫无问题地在包括 _Layout 在内的所有 View 中使用自定义助手:

    @Ou.DataReader.GetType()

当然,在这个例子中,我刚刚将 IDataReader 依赖项公开为一个公共(public)属性,以向您说明它将始终被注入(inject)并且永远不会为 null。在您的特定代码中,您当然可以仅使用助手内的私有(private)只读字段来完成您的任务。

关于asp.net-mvc-3 - 使用 Autofac 将属性注入(inject)自定义 WebViewPage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14933450/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com