Upon the creation of a new item, when posting information from a form back to the controller, it says that no parameter-less constructor could be found. That is expected since the view model used as the model of the view depends on a domain model object.
I then decided to write my own model binder.
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;
}
This solution with the model binder worked just fine having having registered this binder to the ModelBinders.Binders within the NinjectWebCommon.RegisterServices method.
public void RegisterServices(IKernel kernel) {
CompositionRoot.ComposeObjectGraph();
ModelBinders
.Binders
.Add(typeof(NewItemViewModel), new NewItemViewModelBinder(kernel));
}
Besides, I also came across some other posts that were talking about the DependencyResolver. So I thought that if I can write a dependency resolver that would solve all other creation problems, then I'd be out of trouble for the rest.
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;
}
And after setting this new resolver as the dependency resolver for MVC,
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
it didn't work, and I had the same problem as the parameter-less constructor.
So, I have three questions.
- What did I do wrong with the DependencyResolver approach?
- What are the benefits of working with the DependencyResolver versus the ModelBinder?
- When to use either one?