MVC - Как сервисный уровень должен общаться с контроллером - PullRequest
1 голос
/ 17 декабря 2011

Я использовал следующий шаблон для своих действий контроллера:

public ActionResult Create(CreateViewModel model) {
    if( !ModelState.IsValid ) {
        return View(model); 
    }

    var project = new Project {
        Name = model.Name,
        // ...
    };

    projectRepository.Add(project);

    return RedirectToAction("Index");
}

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

public class ProjectService : IProjectService {

    void AddProject(Project project) {
        // do business logic
        // ...

        repository.Add(project);
    }
}

Как мой сервисный уровень может легко взаимодействовать с моим контроллером?

Типы сообщений, которые я хотел бы сообщить контроллеру:

  • Ошибки бизнес-логики / проверки
  • Сбои базы данных (не удалось сохранить и т. Д.)

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

Ответы [ 2 ]

2 голосов
/ 17 декабря 2011

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

Я бы пошел по другому маршруту, предложенному Вутером де Кортом, используйте тип возврата изсервис для объекта обмена сообщениями.Вы можете ввести объект возврата в простом перечислении с различными случаями, с которыми может столкнуться служба.Они выглядят лучше в контроллере, потому что вы можете обрабатывать enum с помощью переключателя / регистра, а не try / catch.

Обновление

Как может выглядеть объект сообщения:

public interface IServiceAbc
{
    ServiceResponse InvokeMyService([params]);
}

public enum ResponseScenario
{
    Success,
    DatabaseFailed,
    BusinessRuleViolated,
    ValidationRuleViolated
}

public class ServiceResponse
{
    public ResponseScenario Scenario { get; internal set; }
    public string Message { get; internal set; }
}
1 голос
/ 17 декабря 2011

Если вы хотите возвращать подробные сообщения при возникновении ошибки, вы всегда можете использовать исключения. Может быть, определите свое собственное с конкретными деталями или используйте те, которые уже есть в .NET Framework.

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

...