Eu escrevi um portal ASP.NET WebForms para um cliente. O projeto meio que evoluiu, em vez de ser adequadamente planejado e estruturado desde o início. Conseqüentemente, todo o código é agrupado no mesmo projeto e sem nenhuma camada. Agora, o cliente está satisfeito com a funcionalidade, portanto, gostaria de refatorar o código de modo a ter confiança em liberar o projeto. Como parece haver muitas maneiras diferentes de projetar a arquitetura, gostaria de algumas opiniões sobre a melhor abordagem a ser adotada.
FUNCIONALIDADE
O portal permite que os administradores configurem modelos HTML. Outros "parceiros" associados poderão exibir esses modelos adicionando o código IFrame ao site. Dentro desses modelos, os clientes podem registrar e comprar produtos. Uma API foi implementada usando o WCF, permitindo que empresas externas também fizessem interface com o sistema. Uma seção Admin permite que os administradores configurem várias funcionalidades e visualizem relatórios para cada parceiro. O sistema envia faturas e notificações por email aos clientes.
ARQUITETURA ATUAL
Atualmente, ele está usando o EF4 para ler / gravar no banco de dados. Os objetos EF são usados diretamente nos arquivos aspx. Isso facilitou o desenvolvimento rápido enquanto eu escrevia o site, mas provavelmente é inaceitável mantê-lo assim, pois está acoplando firmemente o banco de dados à interface do usuário. Lógica comercial específica foi adicionada às classes parciais dos objetos EF.
QUESTÕES
O objetivo da refatoração será tornar o site escalável, de fácil manutenção e segurança.
Que tipo de arquitetura seria melhor para isso? Descreva o que deve estar em cada camada, se devo usar o padrão DTO / POCO / Active Record etc.
Existe uma maneira robusta de gerar automaticamente DTOs / BOs para que quaisquer aprimoramentos futuros sejam simples de implementar, apesar das camadas extras?
Seria benéfico converter o projeto de WebForms para MVC?
Respostas:
O padrão ASP.NET MVP é a melhor arquitetura para um aplicativo de formulários da Web ASP.NET de longo prazo . Está entrando em jogo com o conceito de "separação de preocupações", que é de fato uma tendência por trás dos padrões de MV *.
A pergunta sobre por que usá-lo? - abordado em detalhes nesta postagem - ASP.NET MVP
fonte
fonte
Como ElYusubov mencionou, o padrão MVP pode ser ótimo.
O conceito-chave está retirando a maior parte ou toda a sua lógica do code-behind. A lógica não deve estar vinculada a uma página. E se você precisar reutilizar a lógica de uma página em outra? Você será tentado a copiar e colar. Se você estiver fazendo isso, seu projeto se tornará sustentável.
Portanto, para iniciantes, comece a refatorar sua lógica a partir do code-behind e a coloque em uma camada de negócios. Se você conseguiu extrair toda a lógica do code-behind, poderia implementar as interfaces necessárias para ser um verdadeiro MVP.
Verifique também se o acesso aos dados está separado da lógica de negócios. Crie uma camada de dados e comece a refatorar também nesse sentido. Como você está usando o EF4, isso é menos problemático, já que o EF já deve ter esse fim separado. Você poderá mover facilmente todos os seus arquivos EF para outro projeto e simplesmente adicionar uma referência aos projetos que precisam dele. O benefício adicional é que você pode precisar fazer referência ao seu modelo de dados em outros projetos.
Para evitar ser sobrecarregado, refatorar um pouco de cada vez. Sempre que você tocar em um pedaço de código, considere refatorá-lo. Se você fizer isso, com o tempo, seu projeto poderá se tornar mais sustentável.
Editar
Você perguntou sobre a herança do código por trás de uma classe de lógica de negócios. Isso não pode ser feito porque o código por trás da página "é-a". O C # não permite herança múltipla, portanto, a classe code-behind não pode ser uma página e um objeto personalizado. Você precisa separar conceitualmente a lógica. Provavelmente, o código no seu code-behind está fazendo muitas coisas diferentes. Uma classe deve fazer uma coisa e apenas uma coisa. Tente e pense sobre como você pode conceitualmente extrair a funcionalidade existente. Por exemplo, digamos que você tenha uma página de registro e esteja coletando informações do usuário. Você provavelmente tem um botão chamado registrar e um evento de clique associado a esse botão. Nesse caso, você está salvando as informações do usuário e fazendo o processamento necessário. Você pode criar um objeto de registro para lidar com toda essa lógica.
Isso não é apenas uma separação mais limpa, mas também pode ser uma maneira de auto-documentar seu código. Quando alguém lê o seu código, ele vê você chamando um objeto de Registro para saber exatamente o que está acontecendo.
Se você quisesse seguir rigorosamente o padrão MVP, em vez de passar os parâmetros para o objeto Registration, o code-behind implementaria uma interface. A implementação da interface mapeará essencialmente todos os objetos de exibição (campo de texto etc.) para a interface. por exemplo, public string FirstName {get {return txtFirstName.Text; }}
Feito isso, você pode passar a página para o objeto Regisration
Registration.RegisterUser (this);
E esse método RegisterUser usaria a interface como parâmetro
public bool RegisterUser (usuário IUser) {user.FirstName ...}
interface pública IUser {public string FirstName; }
Se esse MVP parecer confuso, concentre-se na refatoração e saiba que o objetivo de tudo isso é maximizar a reutilização de código. Não existe desde que se repita. Esse é o diretor DRY .
fonte