Models, ViewModels, DTOs no aplicativo MVC 3
Tenho uma solução web (no VS2010) com dois subprojetos:
Domain
que contém oModel
classes (mapeadas para tabelas de banco de dados via Entity Framework) eServices
que (além de outras coisas) são responsáveis pelas operações CRUD
WebUI
que faz referência ao projeto Domain
Para as primeiras páginas que criei, usei as classes Model do projeto Domain diretamente como Model em minhas Views fortemente tipadas, porque as classes eram pequenas e eu queria exibir e modificartodo propriedades.
gora, tenho uma página que deve funcionar apenas com uma pequena parte de todas as propriedades do modelo de domínio correspondente. Recupero essas propriedades usando umprojeçã do resultado da consulta na minha classe de serviço. Mas eu precisoproject em um tipo - e aqui estão minhas perguntas sobre as soluções em que consigo pensar:
Eu apresentoViewModels
que vivem noWebUI
projetar e exporIQueryables
e aEF data context
do serviço para o projeto WebUI. Então eu poderia projetar diretamente nesses ViewModels.
Se não quiser expor IQueryables e o contexto de dados EF, coloquei oViewModel
classes noDomain
project, posso retornar os ViewModels diretamente como resultado das consultas e projeções das classes de serviç
Em adição aViewModels
noWebUI
projeto que apresentoData transfer objects
que move os dados das consultas nas classes de serviço para oViewModels
.
s soluções 1 e 2 parecem a mesma quantidade de trabalho e estou inclinado a preferir a solução 2 para manter todas as preocupações com o banco de dados em um projeto separado. Mas de alguma forma, parece errado terVisã -Modelos no projeto Domínio.
@Solution 3 parece muito mais trabalhoso, pois tenho mais classes para criar e me preocupar com o mapeamento Model-DTO-ViewModel. Também não entendo qual seria a diferença entre os DTOs e os ViewModels. Os ViewModels não são exatamente a coleção das propriedades selecionadas da minha classe Model que eu quero exibir? Eles não conteriam os mesmos membros que os DTOs? Por que eu gostaria de diferenciar ViewModels e DTO?
Qual dessas três soluções é preferível e quais são os benefícios e as desvantagens? Existem outras opções?
Agradecemos seu feedback com antecedência!
Edita (porque eu tinha talvez uma parede de texto muito longa e me pediram código)
Exemplo: eu tenho umCustomer
Entidade ...
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public City { get; set; }
// ... and many more properties
}
... e deseja criar uma Visualização que mostre apenas (e talvez permita editar) oName
de clientes em uma lista. Em uma classe de serviço, extraio os dados necessários para o View por meio de uma projeção:
public class CustomerService
{
public List<SomeClass1> GetCustomerNameList()
{
using (var dbContext = new MyDbContext())
{
return dbContext.Customers
.Select(c => new SomeClass1
{
ID = c.ID,
Name = c.Name
})
.ToList();
}
}
}
Então existe um CustomerController com um método de ação. Como isso deve ser?
Desta forma (a) ...
public ActionResult Index()
{
List<SomeClass1> list = _service.GetCustomerNameList();
return View(list);
}
... ou melhor assim (b):
public ActionResult Index()
{
List<SomeClass1> list = _service.GetCustomerNameList();
List<SomeClass2> newList = CreateNewList(list);
return View(newList);
}
No que diz respeito à opção 3 acima, eu diria:SomeClass1
(mora emDomain
project) é um DTO eSomeClass2
(mora emWebUI
project) é um ViewModel.
Estou imaginando se algum dia faz sentido distinguir as duas classes. Por que eu não escolheria sempre a opção (a) para a ação do controlador (porque é mais fácil)? Existem razões para introduzir o ViewModel (SomeClass2
) Em adição ao DTO (SomeClass1
)?