lev*_*nis 2 autofac asp.net-mvc-3
我正在创建一个内部应用程序框架,我们组织中的其他开发团队将使用它来构建MVC应用程序.作为其中的一部分,我正在为所有视图创建菜单结构,从配置中读取并根据当前用户的权限进行修改.要创建菜单作为框架的一部分,我已经创建了WebViewPage一个自定义HTML Helper类的自定义实现,需要依赖于它ApplicationDataReader来构造菜单.
我已经阅读了各种帖子,解释说MVC需要WebViewPage有一个无参数的构造函数,所以我需要使用属性注入.我已经配置了Autofac MVC3集成,包括注册一个ViewRegistrationSource.麻烦的是,当访问依赖属性时,它总是为空.
这是我正在尝试进行的调用的自定义视图页面和帮助程序:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
问题源于InitHelpers被调用(via Layout.Execute())被调用的事实Application_Start,因此没有注册任何依赖项.我知道在视图中注入逻辑并且视图应该简单愚蠢是不好的做法,但这是一个应用程序框架,它需要执行某些设置步骤,使用框架的开发人员必须无法查看.
我能遵循更好的方法吗?
这里有一个类似的问题:Autofac可以将依赖项注入布局视图文件吗?
问题源于在调用Application_Start之前调用InitHelpers(通过Layout.Execute())
我不认为之前有过这样的话Application_Start.我无法重现你的问题.
以下是我所做的步骤,并且完美无缺:
Autofac.Mvc3NuGet定义虚拟接口:
public interface IDataReader
{
}
Run Code Online (Sandbox Code Playgroud)还有一个虚拟实现:
public class DataReader : IDataReader
{
}
Run Code Online (Sandbox Code Playgroud)定义自定义帮助器:
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; }
}
}
Run Code Online (Sandbox Code Playgroud)使用此帮助程序定义自定义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);
}
}
Run Code Online (Sandbox Code Playgroud)将默认视图页面替换为自定义视图页面~/Views/web.config:
<pages pageBaseType="MvcApplication1.OuBaseViewPage">
Run Code Online (Sandbox Code Playgroud)在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));
}
Run Code Online (Sandbox Code Playgroud)现在,您可以愉快地在包括_Layout在内的所有视图中使用自定义帮助程序,而不会出现任何问题:
@Ou.DataReader.GetType()
Run Code Online (Sandbox Code Playgroud)当然,在这个例子中,我刚刚将IDataReader依赖项作为公共属性公开,以说明它将始终被注入并且它永远不会为null.在您的特定代码中,您当然可以仅使用帮助程序中的私有只读字段来完成您的任务.
| 归档时间: |
|
| 查看次数: |
2609 次 |
| 最近记录: |