Принимает ли решение, какие сервисы использовать и в каком порядке логика в методе контроллера MVC? - PullRequest
2 голосов
/ 29 сентября 2011

Я близок к концу нового приложения ASP.NET MVC, которое я разрабатывал, и я понял, что я не на 100% уверен в том, что должно происходить в моих методах контроллера.

Лучше ли для метода действия определить, какие службы / методы вызываются и в каком порядке, например:

AccountService _accountService;
BillingService _billingService;
InvoiceService _invoiceService;

...    

public ActionResult UpgradeAccountPackage(PackageType packageType, int accountId)
{
    _accountService.UpgradeAccountPackage(packageType, accountId);
    _billingService.BillForAccountUpgrade(packageType, accountId);
    _invoiceService.CreateAccountUpgradeInvoice(packageType, accountId);
}

Или лучше придерживаться одного вызова метода для одной службы и позволить этому методу вызывать другие службы / метод поддержки, который ему нужен?

public ActionResult UpgradeAccountPackage(PackageType packageType, int accountId)
{
    // account service upgrades account then calls the BillingService and InvoicService
    // methods called above within this method
    _accountService.UpgradeAccountPackage(packageType, accountId);
}

Я склонялся к тому, чтобы перейти ко второму примеру, так как первоначально казалось, что первый метод каким-то образом представляет собой логику, и это означает, что метод acion должен был по сути знать, как работает процесс обновления учетной записи в моем приложении, что кажется плохой вещью.

Однако, теперь мое приложение почти завершено, оно имеет большой уровень обслуживания, и этот подход привел к тому, что почти все службы сильно зависят от множества других служб, и нет централизованного места, которое решает поток бизнес-транзакций, таких как упомянутый выше, вам нужно немного покопаться в методах обслуживания, чтобы обнаружить процессы.

Я рассматриваю рефакторинг для более близкого сходства со вторым способом, описанным выше, или введение нового уровня между контроллером и уровнем обслуживания, который контролирует поток процессов.

Люди склонны использовать первый или второй метод? Каковы мнения людей?

Ответы [ 3 ]

2 голосов
/ 29 сентября 2011

Я предпочитаю второй метод - его гораздо проще тестировать (с помощью имитаций), и здесь есть логика для повторного использования. В итоге вы получаете Фасады с вашей реальной бизнес-логикой, но это неплохо.

Я не понимаю, почему ваш сервисный уровень полон конкретных зависимостей, хотя ...

Следует помнить, что классы должны полагаться на интерфейсы, а не на реализацию . (и затем связать все это вместе с инструментом Dependancy Injection)

В C # у нас может быть один класс, реализующий много интерфейсов. Таким образом, ваши реализации служб могут реализовывать множество интерфейсов, и все же вызывающему абоненту нужно знать только ту часть, которая им нужна.

Например, у вас может быть AccountTransactionService, который подразумевает IDepositor и IWithdrawer. Если вы реализуете двойной учет, то это может зависеть от IDepositor и IWithdrawer, которые на самом деле просто используют один и тот же экземпляр AccountTransactionService, но это не обязательно, и детали реализации могут быть изменено впоследствии.

Как правило, чем меньше один класс знает о других классах в системе, тем лучше.

1 голос
/ 29 сентября 2011

У вас может быть сервисный уровень, который зависит от нескольких репозиториев (не других сервисов) и который определяет бизнес-операции:

public class MyService: IMyService
{
    private readonly IAccountRepository _accountRepository;
    private readonly IInvoiceRepository _invoiceRepository;
    private readonly IBillingRepository _billingRepository;
    public MyService(IAccountRepository accountRepository, IInvoiceRepository invoiceRepository, IBillingRepository billingRepository)
    {
        _accountRepository = accountRepository;
        _invoiceRepository = invoiceRepository;
        _billingRepository = billingRepository;
    }

    public void UpgradeAccountPackage(PackageType packageType, int accountId)
    {
        ...
    }

}

, а затем ваш контроллер принимает IMyService в качестве зависимости:

public class HomeController: Controller
{
    private readonly IMyService _service;
    public HomeController(IMyService service)
    {
        _service = service;
    }

    public ActionResult UpgradeAccountPackage(PackageType packageType, int accountId)
    {
        _service.UpgradeAccountPackage(packageType, accountId);
        ...
    }
}

Я определяю простые операции CRUD с объектами в репозиториях, и служба объединяет эти многочисленные операции в одну бизнес-транзакцию.

1 голос
/ 29 сентября 2011

Я более внимательно использую первый метод. Позвольте контроллеру контролировать, что происходит. Пусть службы решат, как это произойдет.

Если вы добавите второй слой для управления потоком процессов, из-за чего ваши ActionMethods будут выполнять только один вызов? Если это так, то в этот момент это кажется ненужным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...