I have a brand new project, asp.net mvc 3.
It's all pretty standard, using StructureMap and Nhibernate.
I have 3 projetcs, Core, Infrastructure and UI.
The StructureMap wiring is working just fine, the Index action on a Sample controller is working perfectly.
But, on my create view, I've set the @model to be something like
@model Project.Core.Domain.ISample
On the Controller I have a normal post method :
[HttpPost]
public ActionResult Create(ISample sample)
{
try
{
_repo.Save(sample);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
But I keep getting the "Cannot create an instance of an interface." error.
The last executed lines on the stack are :
[MissingMethodException: Cannot create an instance of an interface.] System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0 System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) +98 System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241 System.Activator.CreateInstance(Type type, Boolean nonPublic) +69 System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +199 System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +572 System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +449 System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +317
I would expect that mvc would use the DependencyResolver internally, if it did, it would be able to create a concrete instance of my ISample interface...but there's a big chance that I understood something completely wrong and this makes no sense...
If I make this simple change to the controller, everything works normally :
public ActionResult Create(Sample sample)
I may be wrong, but this seems wrong to me, everything else is able to use the interface to communicate, why would I have to use the concrete class on the Create action ? This would take away some of the flexibility that the interface gave me.
Does anyone have any idea on how to proceed or if I'm on the wrong track ?
Thanks for your attention.
This is how I got to what I wanted with Darin's help
I've created a new GenericModelBinder (maybe the name could be better)
public class GenericModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
var obj = DependencyResolver.Current.GetService(modelType);
return base.CreateModel(controllerContext, bindingContext, obj.GetType());
}
}
And in global.asax I've added :
ModelBinders.Binders.DefaultBinder = new GenericModelBinder();
Thanks for your help!