使用StructureMap和IDependencyResolver,不能在强类型视图上使用接口并创建操作

时间:2011-02-06 04:31:39

标签: dependency-injection asp.net-mvc-3 structuremap

我有一个全新的项目,asp.net mvc 3.

使用StructureMap和Nhibernate都非常标准。

我有3个项目,核心,基础设施和用户界面。

StructureMap布线工作正常,Sample控制器上的Index操作完美运行。

但是,在我的创建视图中,我将@model设置为

@model Project.Core.Domain.ISample

在Controller上我有一个普通的post方法:

    [HttpPost]
    public ActionResult Create(ISample sample)
    {
        try
        {
            _repo.Save(sample);

            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

但我一直得到“无法创建接口的实例”。错误。

堆栈上最后执行的行是:

  

[MissingMethodException:无法创建接口的实例。]      System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,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

我希望mvc会在内部使用DependencyResolver,如果有的话,它将能够创建我的ISample接口的具体实例......但是我很有可能理解完全错误的东西,这没有任何意义...

如果我对控制器进行这么简单的更改,一切正常:

public ActionResult Create(Sample sample)

我可能错了,但这对我来说似乎不对,其他一切都能够使用界面进行通信,为什么我必须在Create动作中使用具体的类?这会消除界面给我的一些灵活性。

有没有人知道如何继续或者我走错了路?

感谢您的关注。

这就是我在Darin的帮助下达到我想要的方式

我已经创建了一个新的GenericModelBinder(可能名字可能更好)

    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());
    }
}

在global.asax中我添加了:

ModelBinders.Binders.DefaultBinder = new GenericModelBinder();

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

您需要为ISample类型编写自定义模型绑定器才能使其正常工作。 ASP.NET MVC在调用控制器操作时使用默认模型绑定器,以便根据请求值实例化操作参数。

public class MyISampleModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        // Here you need to return the proper instance of the ISample interface
        // based on the request values or some other rules you need
    }
}

然后在Application_Start注册此活页夹:

ModelBinders.Binders.Add(typeof(ISample), new MyISampleModelBinder());