在MVC中可以通过ViewModels访问服务层吗?

时间:2015-06-11 16:35:50

标签: asp.net-mvc viewmodel domainservices

目前,我正在使用DI和服务定位器模式来获取服务实例。 (请注意,Service只是通用术语即时使用,并且只是调用EF存储库并执行数据操作的C#类。它的非WCF服务)

在ViewModel中安装Service实例是否可以?如果是,那么传递Service实例的正确方法是什么?

1>控制器是否应该将服务实例传递给ViewModel。在这种情况下,当控制器被处理时,服务正确处理

2>或者ViewModel是否应该使用DI&服务定位器。在这种情况下,服务将如何处置?

BaseController

public class BaseController:Controller
{
   private MyDomainService _myDomainServiceInstance = null;

    protected MyDomainService MyDomainServiceInstance
    {
        get
        {
            if (_myDomainServiceInstance == null)
            {
                _myDomainServiceInstance = DefaultServiceLocator.Instance.GetInstance<MyDomainService>();
            }

            return _myDomainServiceInstance;
        }
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
        if (_myDomainServiceInstance != null)
        {
            _myDomainServiceInstance.Dispose();
        }
    }
}

控制器

public class MyController:BaseController
{
    public ActionResult DoSomething()
    {
        var model = new SummaryVM(MyDomainServiceInstance);
    }
}

视图模型

public class SummaryVM
{
    MyDomainService _myDomainService = null;        

    public SummaryVM(MyDomainService myDomainService)
    {
        //Approache 1: Controller is passing the service instance
        _myDomainService = myDomainService;
    }

    public SummaryVM()
    {
        //Aprooche 2: Use DI & Service locator pattern to get the instance
        _myDomainService = DefaultServiceLocator.Instance.GetInstance<MyDomainService>();
    }

    public int[] SelectedClients { get; set; }

    public string[] SelectedStates { get; set; }


    public IEnumerable<Clients> PreSelectedClients
    {
        get
        {
            if (SelectedClients == null || !SelectedClients.Any())
            {
                return new List<AutoCompletePreSelectedVM>();
            }

            return _myDomainService.GetClients(SelectedClients);
        }
    }
}

2 个答案:

答案 0 :(得分:0)

我经历过类似的情况。我认为在视图模型中实例化域服务是可以的。域服务可以实现IDisposable,因此我将在get方法中实例化它,而不是将服务创建为属性。

答案 1 :(得分:0)

视图模型旨在向视图提供信息,并且应该特定于应用程序,而不是通用域。控制器应该协调与存储库,服务的交互(我在这里做一些服务定义的假设)等,并处理构建和验证视图模型,还包含确定要呈现的视图的逻辑。

通过将视图模型泄漏到“服务”层,您可以模糊您的图层,现在可以将特定的应用程序和演示文稿与应该关注域级职责的内容混合在一起。

不要混淆概念。如果您的服务处理视图模型,那么它应该是一个表示服务,并在实际模型之上进行分层。 视图模型应该是扁平的,简单的DTO用于与视图绑定。它们不应该是DI容器图的一部分,因为这会使事情复杂化并使代码的推理变得更加困难。