MVC - связь контроллера с сервисным уровнем - PullRequest
6 голосов
/ 17 февраля 2012

В моем приложении ASP.net mvc я использую сервисный уровень и репозитории, чтобы держать свои контроллеры тонкими.Типичное подробное представление, доступное только для чтения, выглядит следующим образом:

public ActionResult Details(int id)
{
    var project = _projectService.GetById(id);

    return View(Mapper.Map<Project, ProjectDetails>(project));
}

Сервисный уровень:

public class ProjectService : IProjectService
{
    public Project GetById(int id)
    {
        var project = _projectRepository.GetProject(id);

        // do some stuff

        return project;
    }
}

public class ProjectRepository : IProjectRepository
{
    public Project GetProject(int id)
    {
        return context.Projects.Find(id);
    }
}

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

В какой ситуации, например, в действии Create, какой подход к этому хорош?

[HttpPost]
public ActionResult Create(CreateProjectViewModel model)
{
    if(!ModelState.IsValid)
    {
        return View(model);
    }

    // TODO

    return RedirectToAction("Index");
}

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

Как должен выглядеть мой контроллер для связи со служебным уровнем?Я хочу, чтобы код в контроллере был как можно более легким.

Ответы [ 3 ]

5 голосов
/ 17 февраля 2012

Вы можете определить двунаправленное отображение, а затем пойти другим путем:

[HttpPost]
public ActionResult Create(CreateProjectViewModel model)
{
    if(!ModelState.IsValid)
    {
        return View(model);
    }

    Project project = Mapper.Map<CreateProjectViewModel, Project>(model);
    // pass the project entity to your service layer
    _projectService.Create(project);

    return RedirectToAction("Index");
}

или, если вы обновляете сущность, вы можете сначала получить существующую сущность, которую хотите обновить, из службы:

[HttpPost]
public ActionResult Update(CreateProjectViewModel model)
{
    if(!ModelState.IsValid)
    {
        return View(model);
    }

    Project project = _projectService.GetById(model.Id);
    Mapper.Map<CreateProjectViewModel, Project>(model, project);

    // pass the project entity to your service layer
    _projectService.Update(project);

    return RedirectToAction("Index");
}
1 голос
/ 17 февраля 2012

Единственный способ, которым я видел это до сих пор, - это вручную создать группу классов преобразования модели, например:

public interface ITransformer<out To, in From>
    where To : class
{
    To Transform(From instance);
}

public class SomeDataToSomeViewModelTransformer : ITransformer<SomeViewModel, SomeDataModel>
{
    public SomeViewModel Transform(SomeDataModel instance)
    {
        return new SomeViewModel
            {
                InvitationId = instance.Id,
                Email = instance.EmailAddress,
                GroupId = instance.Group.Id
            };
    }
}

И другую реализацию Transformer, чтобы вернуться другим путем (ViewModel -> DataModel).И когда контроллер знает, как вызвать правильный преобразователь.

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

0 голосов
/ 17 февраля 2012

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

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

...