首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么时候想在IDependencyResolver上使用IModelBinder?

什么时候想在IDependencyResolver上使用IModelBinder?
EN

Stack Overflow用户
提问于 2015-02-08 21:19:58
回答 1查看 640关注 0票数 1

在创建新项时,当将表单中的信息发回给控制器时,它说不会找到没有参数的构造函数。这是预期的,因为用作视图模型的视图模型依赖于域模型对象。

然后我决定写我自己的模型活页夹。

NewItemViewModelBinder

代码语言:javascript
复制
public class NewItemViewModelBinder : DefaultModelBinder {
    public NewItemViewModelBinder(IKernel kernel) {
        if (kernel == null) throw new ArgumentNullException("kernel");
        this.kernel = kernel;
    }

    protected override object CreateModel(ControllerContext controllerContext
        , ModelBindingContext bindingContext, Type modelType) {
        return kernel.Get(modelType);
    }

    private readonly IKernel kernel;
}

这个使用模型绑定的解决方案在NinjectWebCommon.RegisterServices方法中将这个绑定器注册到NinjectWebCommon.RegisterServices中后,效果很好。

代码语言:javascript
复制
public void RegisterServices(IKernel kernel) {
    CompositionRoot.ComposeObjectGraph();
    ModelBinders
        .Binders
        .Add(typeof(NewItemViewModel), new NewItemViewModelBinder(kernel));
}

此外,我还看到了其他一些关于DependencyResolver的帖子。所以我想,如果我能写一个解决所有其他创建问题的依赖解析器,那么剩下的问题我就不会有麻烦了。

NinjectDependencyResolver

代码语言:javascript
复制
public class NinjectDependencyResolver : NinjectDependencyScope
    : System.Web.Http.Dependencies.IDependencyResolver
    , System.Web.Mvc.IDependencyResolver {
    public NinjectDepencyResolver(IKernel kernel
        , IDependencyScopeFactory factory) : base(kernel) {
        if (kernel == null) throw new ArgumentNullException("kernel");
        if (factory == null) throw new ArgumentNullException("factory");
        this.kernel = kernel;
    }

    public IDependencyScope BeginScope() { 
        return factory.Create(kernel.BeginBlock()); 
    }

    public object GetService(Type serviceType) {
        return kernel.TryGet(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType) {
        return kernel.GetAll(serviceType);
    }

    public void Dispose() { base.Dispose(); }

    private readonly IKernel kernel;
    private readonly IDependencyScopeFactory factory;
}

在将这个新的解析器设置为MVC的依赖解析器之后,

代码语言:javascript
复制
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));

它没有工作,而且我遇到了与无参数构造函数相同的问题。

所以,我有三个问题。

  1. 我的DependencyResolver方法做错了什么?
  2. 使用DependencyResolver和ModelBinder有什么好处?
  3. 什么时候用哪一种?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-08 22:05:45

根据专业ASP.NET MVC 4,第308页,您不应该在应用程序中使用IDependencyResolver。

您应该在应用程序中使用DEPENDENCYRESOLVER吗?您可能会尝试从自己的应用程序中使用IDependencyResolver。抵制住这种诱惑。依赖解析器接口正是MVC所需要的--仅此而已。它并不打算隐藏或替换依赖注入容器的传统API。大多数容器都有复杂而有趣的API;实际上,您很可能会根据API和它提供的特性来选择容器,而不是其他任何原因。

IDependencyResolver旨在向MVC框架提供依赖关系,而不是向应用程序提供依赖关系。

IDependencyResolver的实现方式遵循服务定位器(反)模式

此外,IDependencyResolver不需要在MVC中使用DI。更好的选择是使用IControllerFactory将依赖项注入控制器和使用其他扩展点(如IModelBinder),使用构造函数注入,而不是服务位置。

至于使用IModelBinder,您正在使用示例中的良好实践,因为您正在执行构造函数注入(尽管有些人可能认为模型不应该有依赖关系,但这取决于您的框架设计)。

作为开发人员,我们总是试图尽可能多地概括设计,毕竟,这通常是最好的做法。然而,当涉及到DI时,我们必须与这种冲动作斗争。对于DI,最好让每个类按类型显式地请求它自己的依赖项,因此很明显,类需要什么才能起作用。服务定位器位于这个频谱的另一端--它是一个服务黑匣子,它可能包含或不包含应用程序运行所需的所有类型,并且使应用程序更难以配置。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28399484

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档