2017-08-01 20 views
1

我有一个自定义WebViewPage,我希望SimpleInjector解决它的一些依赖关系。由于MVC实例化这个类的方式,似乎我不能使用构造器注入。SimpleInjector和自定义WebViewPage

我已启用明确属性注入,如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

有此相关的问题 - https://stackoverflow.com/questions/38704650 - 但这是关于在视图中使用自定义WebViewPage类中的某些内容。这个位对我来说很好,但不是属性注入。 –

+1

如果我没有理解错误 - 你是说MVC不允许构造器注入???(因为我通过构造函数注入了控制器的依赖关系) –

+0

'似乎我不能使用构造器注入,因为MVC实例化的方式这个班'这很奇怪。你有看过这个吗? :https://stackoverflow.com/questions/19925290/dependencyresolver-setresolver-not-working – Stefan

回答

1

我同意Remo Gloor's answer和斯特凡声明:

但正如其他人说你不应该做视图注射反正。您的视图应该是愚蠢的,只是将视图模型呈现为HTML。任何需要依赖的应该在控制器或服务中完成。

这就是说,如果你真的,真的,真的需要这个(你不应该),我认为这是创建一个自定义IViewEngine的问题。

警告:下面的代码不是!测试AT ALL *

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)); 
相关问题