none
Melhor Prática/Padrão Entity Framework + MVC RRS feed

  • Pergunta

  • Pessoal, estou desenvolvendo um projeto com MVC 4, como já fiz alguns passei por experiências boas e ruins, no decorrer da aprendizagem você vai sentindo falta de algumas coisas. No meu caso foi uma camada de lógica de negócios, queria saber como vocês fazem para organizar o projeto.

    No meu caso fica assim:

    Model é passado para o controller, onde faz a validação (no momento a lógica de negócio fica nele), o Controller instancia o UnitOfWork que por sua vez instancia um repositório generico onde realiza a ação desejada.

    Mas como tinha dito, sinto falta de uma camada, onde eu possa realizar a lógica de negócios, pensei que ficaria mais ou menos assim.

    Model > Controller > Camada de Lógica > UnitOfWork > RepositorioGenerico

    O repositório genérico teria um crud, então os métodos específicos eu faria na camada de negócios ex:

    ListarRotinasCanceladas ou CancelarRotina.

    Conto com a colaboração de vocês, obrigado!

    quarta-feira, 10 de julho de 2013 19:31

Respostas

  • O primeiro passo é criar um projeto "Class Library", o nome fica a sua escolha mas por uma questão de padronização costumo usar algo como NomeProjetoService.

    2. Acrescente interfaces para suas classes de negócios ex:

    namespace NomeProjetoService
    {
        public interface IRotinas
        {
            IEnumerable<Rotinas>ListarRotinasCanceladas();
            void CancelarRotina(int id);
        }
    }
    

    Crie suas classes de serviço implementando a interface criada:

    namespace NomeProjetoService {

    public class RotinasService : IRotinas { public IEnumerable<Rotinas> ListarRotinasCanceladas() { //PROCESSA E RETORNA A LISTA DE ROTINAS } public void CancelarRotina(int id) { //PROCESSA E CANCELA A ROTINA } } }

    No controller você usa injeção de dependência para acrescentar sua camada de serviços.


    • Editado João_ PradoModerator sexta-feira, 12 de julho de 2013 01:55 finalização do post
    • Sugerido como Resposta Paulo M Dalbosco sexta-feira, 12 de julho de 2013 11:14
    • Marcado como Resposta KvnAllen segunda-feira, 15 de julho de 2013 18:15
    sexta-feira, 12 de julho de 2013 01:55
    Moderador
  • Não é exatamente isso.

    As interfaces servem como uma assinatura abstrata da classe concreta. Desta maneira você pode instanciar as mesmas sem se preocupar com a implementação.

    Um exemplo clássico seria por exemplo mudar de banco de dados. Imagine que você use MySQL e deseje trocar para o SQL Server.

    Você não precisaria mexer uma linha de código nos seus controllers, basta implementar as classes concretas baseadas na interface usando o SQL Server.

    Para criar Unity Tests o uso das interfaces é quase obrigatório. 

    A injeção de dependência serve para que ao usar as interfaces a mesma instancie a parte concreta das mesmas sem precisar de você fazer isso "na unha".

    • Editado João_ PradoModerator sábado, 13 de julho de 2013 17:32 Complemento a resposta
    • Marcado como Resposta KvnAllen segunda-feira, 15 de julho de 2013 18:15
    sábado, 13 de julho de 2013 17:30
    Moderador

Todas as Respostas

  • Regra de negócio que você fala é validar os objetos vindo da View?

    Se for isso uso o "CustomValidationAttribute"

    Vc escreve suas classes de regras, decora sua propriedades no model.
    Assim sendo ele vai aplicar as validações e no controller teremos o "ModelState.IsValid", que irá controlar se o retorno é false ou true.


    Paulo Marcelo Dalbosco


    quinta-feira, 11 de julho de 2013 14:43
  • Não não, seria uma camada para lógica de negócios mesmo, exemplo.

    Pessoa tem nome e endereço.

    O nome é obrigatório, essa validação eu faço no Model mesmo com Data Annotations.

    Mas eu tenho outra validação, se o nome da pessoa for Kevin, o nome recebe + "Allen" automaticamente.

    O que eu queria era uma camada para essas validações, para não ficar tudo no controller.

    quinta-feira, 11 de julho de 2013 16:06
  • Bom, a questão da camada lógica de negócios vai depender da sua organização e também a forma de estruturar o código.

    View -> Camada de apresentação de dados e lógica de programação referente aos efeitos visuais.

    Model -> Camada que representa os dados que serão visualizados, podendo ser uma propriedade List<T> para popular um grid, propriedade string para apresentar um nome e etc.

    Controller -> Camada que irá conter várias Actions onde dentro delas conterão as regras de negócio daquela chamada, mas por questão de organização de código, nada impede de você criar mais uma camada para deixar o seu código bem modular e estruturado.  Se você for ter por exemplo uma Action com 50 linhas de código, mais fácil vc criar uma nova camada, msm porque fica mais fácil visualizar. Essa é minha singela opinião.


    quinta-feira, 11 de julho de 2013 16:21
  • Você pode criar uma camada de serviço entre a camada de dados e o projeto MVC.

    Depois basta instanciar a mesma nos controllers via injeção de dependência ou na unha mesmo.

    quinta-feira, 11 de julho de 2013 18:55
    Moderador
  • Você pode criar uma camada de serviço entre a camada de dados e o projeto MVC.

    Depois basta instanciar a mesma nos controllers via injeção de dependência ou na unha mesmo.

    Eu estava lendo sobre isso, você tem algum exemplo/projeto-modelo ?

    Agradeço ao Cesar Mendes também pela resposta!

    obrigado.

    quinta-feira, 11 de julho de 2013 23:09
  • O primeiro passo é criar um projeto "Class Library", o nome fica a sua escolha mas por uma questão de padronização costumo usar algo como NomeProjetoService.

    2. Acrescente interfaces para suas classes de negócios ex:

    namespace NomeProjetoService
    {
        public interface IRotinas
        {
            IEnumerable<Rotinas>ListarRotinasCanceladas();
            void CancelarRotina(int id);
        }
    }
    

    Crie suas classes de serviço implementando a interface criada:

    namespace NomeProjetoService {

    public class RotinasService : IRotinas { public IEnumerable<Rotinas> ListarRotinasCanceladas() { //PROCESSA E RETORNA A LISTA DE ROTINAS } public void CancelarRotina(int id) { //PROCESSA E CANCELA A ROTINA } } }

    No controller você usa injeção de dependência para acrescentar sua camada de serviços.


    • Editado João_ PradoModerator sexta-feira, 12 de julho de 2013 01:55 finalização do post
    • Sugerido como Resposta Paulo M Dalbosco sexta-feira, 12 de julho de 2013 11:14
    • Marcado como Resposta KvnAllen segunda-feira, 15 de julho de 2013 18:15
    sexta-feira, 12 de julho de 2013 01:55
    Moderador
  • Entendi.

    Qual seria o melhor modo para realizar uma injeção de dependências no controller ? Nunca fiz isso, então será um novo desafio :)



    • Editado KvnAllen sexta-feira, 12 de julho de 2013 10:45 Melhoria no texto.
    sexta-feira, 12 de julho de 2013 10:21
  • Gosto muito do CastleWindsor, tem gente que prefere o NDependency ou Ninject.

    No começo você pode achar complicado mas depois que aprende fica difícil não trabalhar com injeção de dependência.

    Procura no google por esses dois, tem muita referência e documentação na rede sobre os mesmos.

    Abaixo um tutorial para MVC3 DO Castle:

    http://docs.castleproject.org/Windsor.Windsor-tutorial-ASP-NET-MVC-3-application-To-be-Seen.ashx

    sexta-feira, 12 de julho de 2013 18:43
    Moderador
  • Eu estava dando uma olhada no Unity da Microsoft, em um teste de desempenho o Ninject foi o mais lento, e eu dou muito valor a desempenho do sistema =)

    Então, como eu uso Entity, encontrei no codeplex um tutorial:

    http://www.codeproject.com/Articles/207820/The-Repository-Pattern-with-EF-code-first-Dependen

    Você que já entende bem, o que achou do código ? 

    Pelo que entendi "DI" é basicamente utilizar interfaces no lugar das classes para não precisar instanciá-las, ou estou errado? Só queria saber como ele sabe o que fazer quando é chamado o método da interface.

    Preciso estudar mais :)

    sábado, 13 de julho de 2013 13:03
  • Não é exatamente isso.

    As interfaces servem como uma assinatura abstrata da classe concreta. Desta maneira você pode instanciar as mesmas sem se preocupar com a implementação.

    Um exemplo clássico seria por exemplo mudar de banco de dados. Imagine que você use MySQL e deseje trocar para o SQL Server.

    Você não precisaria mexer uma linha de código nos seus controllers, basta implementar as classes concretas baseadas na interface usando o SQL Server.

    Para criar Unity Tests o uso das interfaces é quase obrigatório. 

    A injeção de dependência serve para que ao usar as interfaces a mesma instancie a parte concreta das mesmas sem precisar de você fazer isso "na unha".

    • Editado João_ PradoModerator sábado, 13 de julho de 2013 17:32 Complemento a resposta
    • Marcado como Resposta KvnAllen segunda-feira, 15 de julho de 2013 18:15
    sábado, 13 de julho de 2013 17:30
    Moderador
  • Muito obrigado João Prado ! Sua explicação foi muito esclarecedora !

    Agora, outra dúvida me surgiu, se a injeção instancia a parte concreta, digamos que eu implementasse duas vezes a mesma interface, o que aconteceria ? E a interface deve seguir o mesmo nome da classe concreta? Ex:

    PessoaRepository.cs e IPessoaRepository.cs

    Obrigado!

     

    domingo, 14 de julho de 2013 19:35
  • Na questão dos nomes não é necessário seguir o mesmo nome, é uma questão de convenção. Claro que isso também facilita a compreensão dos seus projetos.

    Quanto à injeção de dependência você vai perceber que vai ter que inicializar a mesma de alguma maneira (cada framework tem sua inicialização).

    Nesta hora você escolhe quais classes concretas serão instanciadas para as interfaces em questão.

    Não se esqueça de marcar como resposta os posts que lhe ajudaram Ok?

    Abraços e bom desenvolvimento.

    segunda-feira, 15 de julho de 2013 17:08
    Moderador
  • Olá 

    Eu tenho alguns vídeos no youtube, que podem ajudar com a estrutura  que você está procurando.

    http://www.youtube.com/watch?v=C-jxeVeauJM

    Este vídeo fala especificamente sobre Entity Framework + MVC4 + Ninject

    Espero que ajude.


    Parmezani Analista de Sistemas - Consultor .Net http://parmezaninet.blogspot.com.br/

    sexta-feira, 15 de novembro de 2013 22:33