简体   繁体   中英

ASP.NET MVC - Querying into View Models Outside the Controller

I have a couple of repositories that return entities (persistence models) into the list of view models. All the mappings of entities into view models happen in the controller. Example:

public class TestController : Controller
{
    private readonly ITestRepository repository;

    public TestController (ITestRepository repository)
    {
        this.repository = repository;
    }

    public ActionResult Index(SomeFilter filter)
    {
        var viewModelList = repository.GetTestEntityBy(filter.TestId, filter.Name) // returns IQueryable<TestEntity>
            .Select(x => new TestViewModel // linq projection - mapping into the list of viewModel
            {
                Id = x.Id,
                Name = SomeFormatter.FormatName(
                    x.TestId,
                    x.TestAddress1,
                    x.TestAddress2),
                Url = UrlFormatter.Format(x.TestName, Url.Action("ChangeValue", "TestController", new { x.id })),
                AllergyType = x.TestType
                Notes = x.Notes,
                ...
            });

        return View(viewModelList);
    }
}

Question: What is the best way (pattern?, location?) to store this code (mappings, url formatters, etc.) outside the controller? Eventually I end up creating static classes in the Models folder. Thank you!

Recently I've read a few nice articles about refactoring controllers and moving the code to application services:

7 Keep Controllers Thin

http://www.codemag.com/Article/1405071

Best Practices – Skinny Controllers

http://www.arrangeactassert.com/asp-net-mvc-controller-best-practices-%E2%80%93-skinny-controllers/

So I did some refactoring and the controller now looks:

public class TestController : Controller
{
    private readonly ITestApplicationService service;

    public TestController (ITestApplicationService service)
    {
        this.service = service;
    }

    public ActionResult Index(SomeFilter filter)
    {
        var viewModelList = service.GetModelList(filter, Url);
        return View(viewModelList);
    }
    ...
}

Created a new Application Service:

public interface ITestApplicationService
{
    IQueryable<TestViewModel> GetModelList(SomeFilter filter, UrlHelper url);
    void Save(TestViewModel model);
    void Delete(int id);
}

public class TestApplicationService
{
    private readonly ITestRepository repository;

    public TestApplicationService(ITestRepository repository)
    {
        this.repository = repository;
    }

    public IQueryable<TestViewModel> GetModelList(SomeFilter filter, UrlHelper url)
    {
       var viewModelList = repository.GetTestEntityBy(filter.TestId, filter.Name) // returns IQueryable<TestEntity>
        .Select(x => new TestViewModel // linq projection - mapping into the list of viewModel
        {
            Id = x.Id,
            Name = SomeFormatter.FormatName(
                x.TestId,
                x.TestAddress1,
                x.TestAddress2),
            Url = UrlFormatter.Format(x.TestName, url.Action("ChangeValue", "TestController", new { x.id })),
            AllergyType = x.TestType
            Notes = x.Notes,
            ...
        });

        return viewModelList;
    }
    ...
}

Please let me know if anyone has some other thoughts, ideas, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM