DI与ASP.NET MVC中的viewmodel

Jos*_*ees 2 asp.net-mvc dependency-injection inversion-of-control viewmodel

我是第一次学习IoC,但无法弄清楚它如何与标准ASP.NET MVC控制器中的视图模型和模型绑定一起工作.假设我有一个使用紧耦合存储库和视图模型的基本控制器.

public class Sample
{
    [HttpGet]
    public ActionResult Index()
    {
        var repo = new SampleRepository();
        var model = new SampleViewModel();
        model.SampleItems = repo.Get();
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(SampleViewModel model) 
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想使用DI从它的依赖类中松散地耦合这个控制器,所以我在via构造函数注入中注入了存储库和viewmodel

public class Sample
{
    private readonly ISampleRepository _sampleRepository;
    private readonly ISampleViewModel _sampleViewModel;

    public Sample(
          ISampleRepository sampleRepository,
          ISampleViewModel sampleViewModel)
    {
        _sampleRepository =  sampleRepository;
        _sampleViewModel =  sampleViewModel;
    }

    [HttpGet]
    public ActionResult Index()
    {
         _sampleViewModel.SampleItems = _sampleRepository.Get()

         return View(_sampleViewModel);
    }

    [HttpPost]
    public ActionResult Index(SampleViewModel model) 
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,我现在通过接口注入一个viewmodel但是HttpPost Action需要一个具体的SampleViewModel来进行模型绑定?

我误解了它是如何工作的吗?我是否应该尝试从控制器中松散地耦合我的视图模型,或者这只是需要紧密耦合才能使模型绑定器工作的东西?我已经看到了那些人们使用服务层将视图模型返回给控制器的代码,我知道你也可以编写一个自定义模型绑定器,但这对我想要做的事情来说似乎有点过分了?我所追求的是一种注入基本视图模型的方式,然后可以由视图用于GET和POST.

Nig*_*888 5

viewmodel实际上并没有任何事情.它基本上只是一个DTO,可以将数据从控制器传输到视图.根据定义,它不能具有任何依赖性.相反,它是应用程序运行时状态的一部分.

注入运行时数据是反模式.相反,您的控制器应该创建一个viewmodel的实例,因为它总是希望返回一个.没有理由嘲笑它进行测试,也没有理由替换它的实现.因此,也没有理由对它进行抽象(接口或抽象类).

public class Sample
{
    private readonly ISampleRepository _sampleRepository;

    public Sample(
          ISampleRepository sampleRepository)
    {
        _sampleRepository =  sampleRepository;
    }

    [HttpGet]
    public ActionResult Index()
    {
        var sampleViewModel = new SampleViewModel()
        {
            SampleItems = _sampleRepository.Get(),
            // Other initialization here...
        };

        return View(sampleViewModel);
    }

    [HttpPost]
    public ActionResult Index(SampleViewModel model) 
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)