【问题标题】:Model (ViewModel) binding when model needs dependencies injected模型需要注入依赖时的模型(ViewModel)绑定
【发布时间】:2013-05-21 20:52:25
【问题描述】:

我在 ASP.Net MVC 应用程序中使用 Ninject 进行依赖注入(这是我第一个使用 Ninject 或 DI 的项目)。

我选择使用模型-视图-视图模型模式。视图模型将提供我将绑定到实际视图的所有属性,但还需要访问数据库以获取数据列表等内容。例如:

public class CreateGetIncidentViewModel
{

    private IDBContext _dbContext = null;

    [Required]
    public EmployeeType EmployeeType { get; set; }


    [Required]
    [StringLength(50)]
    public string Department { get; set; }

    /
    public IEnumerable<SelectListItem> GetEmployeeTypeSelectList()
    {
        // Simplified for brevity
        var employeeTypes = _dbContext.EmployeTypes.Where().... // Go select the employee types

        var employeeTypeSelectList = new List<SelectListItem>();

        foreach(var employeeType in employeeTypes){
            employeeTypeSelectList.Add(new SelectListItem(){
                // Set select list properties
            });
        }           

        return employeeTypeSelectList;
    }
}

我的问题是:

  • IDBContext 是 Ninject 中已注册的依赖项。通过实例化直接访问具体类型是不行的。
  • 我必须以某种方式将该依赖项注入到此类中,或者以某种方式通过已解决依赖项的其他类访问该依赖项。

鉴于我的 ViewModel 经常由 ASP.Net MVC 通过模型绑定自动补充,我如何将我的依赖项添加到我的 ViewModel 中?

我经历了多种方式,但它们看起来都很脏。我可以(但不想)

  • 实施服务定位器模式,只需从 ViewModel 中解决我的 IDBContext 依赖关系。
  • 在我的控制器中解析 IDBContext 并在手动构建 ViewMode 时将其传递到我的 ViewModel 中,即new CreateGetIncidentViewModel(dbContext);
    • 这并不能解决视图模型被 MVC 水合的问题,尽管当模型被发布到动作时

建议?

【问题讨论】:

    标签: asp.net-mvc mvvm dependency-injection ninject


    【解决方案1】:

    鉴于我的 ViewModel 经常被 ASP.Net MVC 自动补水 通过模型绑定,如何将我的依赖项添加到我的 ViewModel 中?

    您可以编写一个自定义模型绑定器,将依赖项注入到视图模型构造函数中。

    话虽这么说,恕我直言,在 ASP.NET MVC 中使用 MVVM 模式从一开始就是错误的方法,如果你这样做,你必须准备好承受很多痛苦。你准备好了吗?

    如果没有,我会向您推荐以下内容:

    Controller -> Domain model -> View model -> View
    

    在此模式中,您让控制器知道存储库(DbContext - 由您的 DI 框架自动注入其中)。

    流程一:

    1. 控制器收到用户的请求
    2. 控制器使用存储库查询一个或多个域模型
    3. 控制器使用映射层将这些域模型映射到视图模型
    4. 控制器将此(single)视图模型传递给视图进行渲染

    流程2:

    1. 控制器接收来自视图的请求(例如表单提交)
    2. 模型绑定器会自动将请求正文绑定到一个单一视图模型,您的控制器操作会将其作为参数
    3. 控制器正在使用映射层将此视图模型映射到一个或多个域模型
    4. 控制器正在使用存储库来更新这些域模型。

    在这个示例中,视图模型不知道任何关于任何存储库或数据访问或 DbContexts 的信息。视图模型是视图的表示。域模型和视图之间的映射是控制器的职责(可以委托给映射层)。我个人使用AutoMapper 来执行我的域模型和视图模型之间的映射。

    【讨论】:

    • Darin,通过 MVVM,我所指的正是您所建议的。控制器 -> 模型 -> 视图模型 -> 视图。是否有我缺少的术语?每当我查找 MVVM 时,它指的是 ASP.Net MVC,我已经看到了您所描述的模式。让我知道是否有更好的方法来引用这个结构。谢谢!
    • @RyanGriffith MVVM Darin 提到的是 WPF 数据绑定 MVVM 模式。您使用的是 MVC 设计模式(它是控制器),但具有自定义表示模型。
    • 感谢@Fendy 和 Darin 的帮助
    【解决方案2】:

    如果您希望采用 Darin 提到的自定义模型绑定器路线,请查看:https://stackoverflow.com/a/24166483/71906

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      • 2018-01-16
      • 1970-01-01
      • 2012-06-06
      • 2016-07-20
      • 2021-04-17
      • 2016-02-11
      相关资源
      最近更新 更多