在创建新项时,当将表单中的信息发回给控制器时,它说不会找到没有参数的构造函数。这是预期的,因为用作视图模型的视图模型依赖于域模型对象。
然后我决定写我自己的模型活页夹。
NewItemViewModelBinder
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中后,效果很好。
public void RegisterServices(IKernel kernel) {
CompositionRoot.ComposeObjectGraph();
ModelBinders
.Binders
.Add(typeof(NewItemViewModel), new NewItemViewModelBinder(kernel));
}此外,我还看到了其他一些关于DependencyResolver的帖子。所以我想,如果我能写一个解决所有其他创建问题的依赖解析器,那么剩下的问题我就不会有麻烦了。
NinjectDependencyResolver
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的依赖解析器之后,
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));它没有工作,而且我遇到了与无参数构造函数相同的问题。
所以,我有三个问题。
发布于 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,最好让每个类按类型显式地请求它自己的依赖项,因此很明显,类需要什么才能起作用。服务定位器位于这个频谱的另一端--它是一个服务黑匣子,它可能包含或不包含应用程序运行所需的所有类型,并且使应用程序更难以配置。
https://stackoverflow.com/questions/28399484
复制相似问题