Usando MS MVC e DDD, Como e onde definir uma classe parâmetro MVC ActionMethod que envolve uma entidade, um objeto de valor, e alguns campos extras?
-
13-09-2019 - |
Pergunta
Eu sou apenas à beira de ir "Ah ha!" quando se trata de codificação Domain Driven projeto. A questão é Como e onde definir uma classe parâmetro MVC ActionMethod que envolve uma entidade, um objeto de valor, e alguns campos extras? As classes de objetos entidade e valor são definidos no meu repositório.
Do I:
- Criar uma classe personalizada no repositório de implementação das outras classes (para obter as propriedades de todos em uma única classe), e adicionar mais algumas propriedades para os campos extras?
- Criar a entidade / valor aulas objeto poco em um repositório e criar uma classe composta referência a esses objetos na minha classe de controlador, então use isso como o tipo de parâmetro ActionMethod?
- Algo mais?
O formulário de pedido de simplesmente recolhe alguns campos de classe ao cliente, um endereço de correspondência, e uma forma poucos detalhes como a forma como eles nos encontraram. O conteúdo não é importante, só que ele detém informações de várias pocos.
Eu sei MVC irá coincidir com os campos do formulário enviada para as propriedades do Poco no parâmetro ActionMethod como o seguinte:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult RequestCatalog()
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestCatalog(Customer customer)
Assim customer.firstName é obrigado a firstName na forma postados automaticamente.
Eu tenho o seguinte:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestCatalog(string fname, string lname, string address,
string city, string state, string zip, string phone, string howTheyFoundUs)
Mas quero ter algo como:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestCatalog( RequestForm requestForm)
Qualquer pensamento?
Solução
Em primeiro lugar é preciso perceber que o modelo de domínio deve ser definido de forma independente do quadro de tempo de execução (MVC). Imagine que no futuro você deve ser capaz de expor o modelo de domínio como um serviço WCF, ou um cliente rico WPF / Silverlight, ou um trabalho em lotes, ou qualquer outra coisa ...
Isto significa que todos modelagem deve ser não coagidos por detalhes técnicos. Como você armazenar seus dados e os detalhes de como os objetos de domínio são consumidos deve ser (em grande parte) ignoradas nesta fase do processo de design.
Você deve sempre se perguntar: Será que esta classe faz sentido como parte do domínio puro
No seu caso específico, a maioria de seus sons de entrada como ele pertence a uma classe de clientes com uma estrutura semelhante a este
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Phone { get; set; }
public Address Address { get; set; }
}
e a classe de endereço é definido de forma semelhante.
Agora, a pergunta que você precisa perguntar a si mesmo (ou qualquer especialistas em domínio que você está trabalhando com): Será que o howTheyFoundUs
pertencem à classe cliente? Ou é um conceito de domínio em seu próprio direito? Ou é realmente apenas uma peça específica de aplicativo de dados que não têm nada a ver com o modelo de domínio em tudo? A resposta a essas perguntas irá orientar como você acaba modelando sua entrada.
Como um aparte, a propriedade de telefone acima olhares duvidosos para mim, mas é um exemplo muito bom de como os detalhes de implementação (neste caso ASP.NET MVC) pode vazar para o modelo.
Um número de telefone deve realmente ser um objeto de valor em seu próprio direito (ver este blog para um tratamento relacionado deste assunto), mas o ModelBinder padrão do ASP.NET requres um tipo Primite. A melhor opção seria a de implementar um ModelBinder personalizado que pode analisar um número de telefone em um objeto adequado.
Outras dicas
Não há nada para impedi-lo usando Request.Form em seu método de ação.
por exemplo.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestCatalog(Customer customer)
{
var howTheyFoundUs = Request.Form["howTheyFoundUs"];
// ...
}