我有一个自定义WebViewPage
,我希望SimpleInjector解决其中的一些依赖项。由于MVC实例化这个类的方式,似乎我不能使用构造函数注入。
我已按照SimpleInjector documentation中的说明启用了明确的属性注入。但是这些属性并没有被注入 - 它们总是null
。
自定义WebViewPage类:
public abstract class CustomWebViewPage<T> : WebViewPage<T>
{
[Import]
public IMyDependency Dependency { get; set; }
public void UseDependency()
{
Dependency.DoStuff(); // Dependency is null
}
}
IOC设置:
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
container.Options.PropertySelectionBehavior = new ImportPropertySelectionBehavior();
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.Register<IMyDependency, MyDependency>();
我是否需要连接其他任何东西才能使其正常工作?我已经尝试使用SimpleInjector注册自定义WebViewPage(将WebViewPage<>
映射到CustomWebViewPage<>
并使我的类非抽象),但这也不起作用。
为了清楚起见,所有其他属性和构造函数依赖注入都在应用程序中工作 - 只是不适用于这个特定的类。
答案 0 :(得分:1)
我同意Remo Gloor's answer和Stefan的陈述:
但正如其他人所说,无论如何你都不应该观看注射。您的视图应该是愚蠢的,只需将视图模型呈现为HTML。任何需要依赖的事情都应该在控制器或服务中完成。
那就是说,如果你真的,真的,真的需要这个(你不应该这样),我认为这是创建自定义IViewEngine
的问题。
警告:以下代码不是!全部测试*
internal class PropertyInjectionViewEngineDecorator : IViewEngine
{
private readonly ConcurrentDictionary<Type, Registration> registrations = new ConcurrentDictionary<Type, Registration>();
private readonly IViewEngine decoratee;
private readonly Func<Type, Registration> createRegistration;
public PropertyInjectionViewEngineDecorator(IViewEngine decoratee, Container container)
{
this.decoratee = decoratee;
this.createRegistration = type => Lifestyle.Transient.CreateRegistration(type, container);
}
public ViewEngineResult FindPartialView(ControllerContext context, string partialViewName, bool useCache) =>
this.InitializeView(this.decoratee.FindPartialView(context, partialViewName, useCache));
public ViewEngineResult FindView(ControllerContext context, string viewName, string masterName, bool useCache) =>
this.InitializeView(this.decoratee.FindView(context, viewName, masterName, useCache));
public void ReleaseView(ControllerContext controllerContext, IView view) =>
this.decoratee.ReleaseView(controllerContext, view);
private ViewEngineResult InitializeView(ViewEngineResult result)
{
if (result.View != null)
{
Registration registration = this.registrations.GetOrAdd(result.View.GetType(), this.createRegistration);
registration.InitializeInstance(result.View);
}
return result;
}
}
您可以将此自定义PropertyInjectionViewEngineDecorator
挂钩到MVC管道中,如下所示:
var razor = ViewEngines.Engines.Single(e => e.GetType() == typeof(RazorViewEngine));
ViewEngines.Engines.Remove(razor);
ViewEngines.Engines.Add(new PropertyInjectionViewEngineDecorator(razor, container));