MVC 3 将实体作为接口传递

Posted

技术标签:

【中文标题】MVC 3 将实体作为接口传递【英文标题】:MVC 3 passing entity as an Interface 【发布时间】:2012-01-03 03:50:27 【问题描述】:

我目前正在使用 Ninject 作为我的 DI 的 MVC 3 项目,业务对象存储在单独的程序集中。我遇到了控制器参数的问题,在发回 CRUD 操作时,我收到错误“无法创建接口的实例”。我知道您无法创建接口的实例,但似乎我可以解决此问题的唯一方法是使用自定义模型绑定器并通过 FormCollection。这看起来真的很混乱,我想尽可能多地保留项目中的特定类型代码 - 因此到处都是接口,并且 Ninject 到 DI 混凝土。不仅自定义模型绑定看起来很乱 - 我不会丢失我的 DataAnnotations 吗?

一些代码来描述我所拥有的:

public ActionResult Create()

    // I'm thinking of using a factory pattern for this part
    var objectToCreate = new ConcereteType();
    return (objectToEdit);


[HttpPost]
public ActionResult Create(IRecord record)

    // check model and pass to repository
    if (ModelState.IsValue)
    
        _repository.Create(record);
        return View();
    

    return View(record);

以前有人遇到过这种情况吗?你是怎么克服的?

谢谢!

【问题讨论】:

【参考方案1】:

但似乎我可以解决此问题的唯一方法是使用自定义模型绑定器

自定义模型绑定器是正确的方法。顺便说一句,您应该使用视图模型作为操作参数,而不是域模型或接口。

不仅自定义模型绑定看起来很乱 - 我不会也丢失我的 DataAnnotations 吗?

我不知道您为什么认为自定义模型绑定器会使事情变得混乱。对我来说,这是将映射逻辑分离为可重用类的好方法。而且,不,您不会丢失 DataAnnotations。它们将在自定义模型绑定器将返回的具体实例上完美运行。

【讨论】:

+1 以下是其中一些要点的详细说明:***.com/questions/2899680/… 谢谢您,您知道使用这种解决方案存在的任何实际示例吗?【参考方案2】:

传递给控制器​​动作的数据只是值的持有者。他们不应该有任何逻辑,所以没有什么可以解耦的。您可以使用具体类型(例如 Record)而不是接口(IRecord)

【讨论】:

那我岂不是打破了松耦合的规则?如果我出于某种原因想要/必须更改具体方法的名称,即 Record 变为 RecordDifferent,该怎么办?我可以让 RecordDifferent 实现 IRecord 并将我的 DI 更改为现在在所有 IRecord 情况下注入 RecordDifferent。 我更喜欢将类用于模型容器和继承,而不是接口。默认情况下,DI 不用于创建传递给操作的对象。我只将 DI 用于真实逻辑,而不用于数据容器 最初并没有真正理解你的意思,但是在这个项目取得了一些进展后,我现在意识到我正在尝试像你所说的那样“解耦”简单的数据容器。在映射数据库表的任何 POCO 对象中都没有行为(还没有),因此没有理由与这些对象进行接口 - 也没有使用工厂来实例化它们。我想我理解的问题是解耦应该真正用于具有行为的对象,而不仅仅是数据属性。 你的控制器里还有一个奇怪的东西。您永远不应该将操作中的输入直接传递到存储库中。这是安全漏洞。 严格来说,它不会直接传递到存储库,所有实体都使用数据注释进行验证,并且在将实体传递到存储库之前,正在检查模型状态的正确性。安全隐患在哪里?没看到?【参考方案3】:

我犯了同样的简单错误。 Ninject 将参数注入到您的构造函数中,但您向 Index Controller 操作添加了参数。

应该是这样的:

public class HomeController : Controller

    private IRecord _record;

    public HomeController(IRecord record)
    
        _record = record;
    

    public ActionResult Index()
    
        ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application. " +
                          _record .HelloWorld();

        return View();
    

有意义吗?

【讨论】:

谢谢,我也犯了同样的错误:(

以上是关于MVC 3 将实体作为接口传递的主要内容,如果未能解决你的问题,请参考以下文章

WebApi 接口参数不再困惑:传参详解

WebApi 接口参数不再困惑:传参详解

MVC控制器传递多个实体类集合到视图的方案总结

C#进阶系列——WebApi 接口参数不再困惑:传参详解

首先通过将类型作为参数传递来动态实例化实体框架数据库中的模型对象

mvc 从视图传递到Controller 多个不同的实体类接收如何做呢?