Tutorial ASP.NET MVC 5 + DDD + EF + AutoMapper + IoC + Dicas e Truques

Arquitetura de Sistemas Corporativos é um tema muito menos explorado do que ASP.NET MVC 5 e nem por isso é menos importante (na verdade é bem mais), neste vídeo tutorial eu mostrarei como criar uma arquitetura padrão DDD utilizando ASP.NET MVC 5.2, Entity Framework, AutoMapper, IoC com Ninject e muitas dicas para criar uma arquitetura modelo e totalmente responsável.

ASP.NET MVC 5 + DDD + EF + AutoMapper + IoC

Como poderão acompanhar nos slides e no vídeo ASP.NET MVC é apenas a ponta do iceberg em uma aplicação corporativa. Quando entramos no mundo real os exemplos dos artigos de sites e livros não nos atendem mais e é necessário buscar mais conhecimento para criar uma aplicação robusta, responsável, testável, escalável e de fácil manutenção.

O modelo DDD (Domain Driven Design) atende muito bem cenários de aplicações corporativas e eu utilizo muito em meus projetos profissionais e pessoais.

Neste vídeo tutorial você aprenderá

  • Criar uma solução padrão DDD
  • Separar a aplicação em camadas
  • Entidades de Domínio
  • Classes de Serviço
  • Criar Contratos (Interfaces)
  • Repositório Genérico
  • Repositório Especializado
  • Criar um Contexto do Entity Framework
  • Trabalhar com Migrations
  • Criar novas convenções do Entity Framework
  • Remover algumas convenções do Entity Framework
  • Sobrescrever o método SaveChanges para persistência de dados
  • Programar com CodeFirst
  • Utilizar FluentAPI para modelar tabelas
  • Criar Relacionamentos entre Entidades e refletindo nas tabelas do banco de dados.
  • Criar e utilizar a camada de Application
  • Trabalhar com classes genéricas de Entidades
  • Abstrair camadas com Injeção de Dependência (IoC)
  • Implementar o Ninject como container de IoC (DI)
  • Utilizar ViewModels
  • Utilizar DataAnnotations para validação de formulários
  • Mapear ViewModels x Entidade de Domínio com AutoMapper
  • Muitas dicas para acelerar sua produção

Este conteúdo é aplicado no meu curso de ASP.NET MVC 5 – Enterprise Applications com uma carga horária de 16 horas, com todo o embasamento teórico, técnico e prático, muitos outros patterns, testes, mocks, serviços REST, manipulação de filtros do ASP.NET MVC e etc são abordados no curso para uma preparação completa do futuro arquiteto desenvolvedor.

SLIDES

VÍDEO (3h00 de duração)

* Assine meu canal no Youtube 🙂

SOURCE

Para download do projeto clique aqui (logo será transferido para o GitHub)

Referências

Vamos continuar enriquecendo o assunto, poste aqui sua opinião ou dúvida 😉

271 ideias sobre “Tutorial ASP.NET MVC 5 + DDD + EF + AutoMapper + IoC + Dicas e Truques

  1. Agora sim Eduardo… este tutorial que estava faltando. Meus parabéns, sempre postando os materiais mais completos de .NET em português da Web.

  2. Ótimo tutorial Eduardo, Parabéns!
    Apenas um comentário não sei se você cita esse problema no vídeo pois ainda não assisti por completo mas olhando a “demo” percebi que ao rodar o projeto ele mostra o seguinte erro: “No Entity Framework provider found for the ADO.NET provider with invariant name ‘System.Data.SqlClient’. Make sure the provider is registered in the ‘entityFramework’ section of the application config file. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.” Se eu fizesse a referencia do EF no MVC provavelmente iria resolver o problema porém iria “furar” alguns conceitos da arquitetura. Obtive esse erro em outro projeto e em pesquisa sobre achei (tutorial: http://robsneuron.blogspot.com.br/2013/11/entity-framework-upgrade-to-6.html) essa resolução que me parece interessante, testei também na sua “demo” e funcionou legal.

    O comentário do Rob’s: “A quirk that I have not got to the bottom of yet is that Copy Local is not enough to ensure that Entity Framework 6 can find the Sql Provider. The final step was to reference a type in the base domain context (which overrides the databasecontext you get from EF). This is echoed elsewhere, on this Stack Overflow answer.”

    Código implementado dentro do contexto para resolução:
    var ensureDLLIsCopied = System.Data.Entity.SqlServer.SqlProviderServices.Instance;

    Abraço!! =)

  3. Eduardo, realmente um material de uma grandeza incrível, meus parabéns pela essa sua iniciativa. Gostaria de informar que a partir de hoje vou adotar aquela nomenclatura e folders solutions em meus próximos projetos, isso foi incrível curti pra caramba, forte abraço e que DEUS te ilume mais ainda…

  4. Eduardo, parabéns pelo vídeo, aprendi muitas coisas. Gostaria de saber caso eu queira criar os unit tests eu devo criar um projeto isolado de tudo isso ou existe um local específico da estrutura da Solution para eu criar o projeto de teste?

    Obrigado.

  5. Não entendo o motivo de utilizar interface, poderia substitui-lá criando uma classe que possua os mesmos métodos “virtual”, sobrescrevendo caso necessário, não seria melhor?

        • Eduardo, como eu estou acostumado a desenvolver o projeto em 4 camadas básicas (Data, Business, Entidade e Presentation), que é da forma que você até comentou na sua própria vídeo aula, estou tendo dificuldade para saber aonde irá ficar as regras de negócio, Application ou Domain. Como saberei em qual camada devo implementar minha regra? Outra coisa, o tratamento das minhas exceções devem ficar somente na Application? Obrigado.

          • Olá Fábio!

            Todo o negócio é no Domain, alguns tratamentos por ex UoW, Log, etc, ficam na application.

            Recomendo a leitura do livro do Evans sobre DDD.

            Abs.

      • Coloquei a minha pergunta no lugar errado..rss…

        Eduardo, como eu estou acostumado a desenvolver o projeto em 4 camadas básicas (Data, Business, Entidade e Presentation), que é da forma que você até comentou na sua própria vídeo aula, estou tendo dificuldade para saber aonde irá ficar as regras de negócio, Application ou Domain. Como saberei em qual camada devo implementar minha regra? Outra coisa, o tratamento das minhas exceções devem ficar somente na Application?

        • Eduardo que me corrija se eu cometer uma gafe.

          Mas, sendo curto, o core da regra de negócio fica na Domain (ex: verifica se há duplicidade antes, ou altera uma propriedade após uma alteração).

          Na Application vc adiciona chamadas a recursos que não fazem exatamente parte da regra de negócio em sí, mas precisam acontecer. (ex: enviar email após cadastro, consumir uma api antes de alteração, adicionar um registro de log(talvez esse ultimo deva ficar no domain))

  6. Parabéns por mais esse excelente material disponibilizado.

    Tenho aprendido muito com seus videos, uma dúvida, fazer a injecao de independencia via [Inject] daria o mesmo que passando via construtor?

    Obrigado pela iniciativa!

  7. Apesar de não comentar aqui eu já vejos seus posts a um tempo, são sempre muito bem formulados e ensinam muitoooooo.
    Parabéns e espero que você mantenha esse espaço por muitos anos.

  8. Eduardo,
    Parabéns pelo material.
    Conteúdo e didática fora de serie, tiro o chapéu para você.
    Você ministra cursos para cidades do interior de São Paulo?
    Gostaria de traze-lo para um treinamento para minha equipe.
    Podemos combinar isso?

  9. Excelente vídeo, muito bom Edu.
    Parabéns pelo seu trabalho frente à comunidade. Sei o quanto, quer dizer imagino, é difícil dispôr de tempo livre para ajudar o próximo; sei que muitas vezes tem que deixar a vida pessoal um pouco de lado por conta disso. Respeito isso em você.
    Abs e sucesso!

  10. Fala Mestre, Eduardo parabéns pelo ótimo trabalho… Tenho aprendido muito com você!
    Well Well, eu segui o seu tutorial referente a arquitetura que era exatamente o que estava buscando, porém fiz algumas modificações com meus toques rsrs… mas não fugiu em nada do que você fez ou da sua lógica com a arquitetura, salvo apenas que eu não to usando o mvc, e sim um webapi (rest), para depois integrar ao meu front com angular.
    Queria ver se poderia me ajudar com algumas dúvidas que surgiram, fui até a camada de applications, criei um proj WebAPI e fiz as menções a camada applications, quando executo ele informa um erro falando que não tem construtor. Poderia me dar uma ajuda?

  11. Eduardo, eu não poderia buscar diretamente do banco os clientes especiais passando os parâmetros pelo repositório ? Sei que o comportamento e quem define quem é cliente especial é o domínio, porém imagine se eu tivesse um milhão de clientes, buscar todos para depois aplicar o filtro acabaria com o desempenho, certo?

  12. Eduardo belo artigo. Tenho uma estrutura parecida com a sua, porem enfrento também algumas duvidas. Como você mesmo disse, algumas questões são visões diferentes sobre o modelo, quais poderíamos levar horas discutindo quem esta certo ou errado. Alguns conceitos do Martin Flower acho que não são facilmente implementáveis quando o domínio do negocio muda constantemente.

    Deixe lhe questionar:

    1: O que você acha de na camada de serviços de aplicação a implementação de ServicesRequest e ServicesResponde, onde estes podem conter varias entidades do domínio. Alguma outra abordagem para centralizar a entrada e saída de dados?

    2: Ainda sobre a camada de serviço de aplicação, entendo que ela deve orquestrar as chamadas de serviço de domínio e repositório, Ou seja, eu não necessito chamar um serviço de domínio elementar(Ex: GetAll()) que não tem nenhuma regra de domínio especificada, entendo que posso chamar o repositório diretamente, concorda?

    3.Serviços externos (Facebook, Twiter, SendGrid, Mailchimp, etc) você separa em uma nova layer ex Serviços de Infraestrutura? Você entende que o acesso externo a dados sai do domínio da aplicação e ela deve ter um domínio separado para tratar das entidades que fazem sentido ao serviço a ser consumido? Se sim, onde você faz o mapeamento entre as entidades do serviço e as entidades do seu domínio?

    4. Alguma maneira de sincronizar o SaveChages da UoW como 2 DataContext (EF + MongoDB) ou ainda, imaginemos que tenho uma inserção em meu Contexto (EF) e em um serviço de terceiro. Como garantir ambas as transações.

    Novamente belo artigo, abraços.

    • Fala Malcon!

      Muito obrigado pelo feedback!

      1 – Talvez uma abordagem CQRS (se eu entendi bem a questão)
      2 – Poder pode, mas eu não gosto (apesar de ferir o YAGNI) eu ainda construo a chamada mesmo assim.
      3 – Eu separo esses serviços sim e se preciso me relacionar eu crio Entidades ou DTOs para depois fazer o mapeamento, sem misturar nada.
      4 – Alguns desses controles pode não funcionar automaticamente no UoW, nesse caso é necessário controlar a transação na mão ou se ambas tecnologias permitirem o uso de um TransactionScope, usar esse cara para controlar tudo.

      Abs!

  13. Primeiramente gostaria de agradecer por está contribuição a comunidade, seu artigo está muito bom e sua aula foi muito boa.
    Gostaria se possível que você me informa-se um sobre um problema que está ocorrendo quando tento replicar sua aplicação. Ao executar o comando Enable-“Migrations o sistema está me retornando o erro The type initializer for ‘System.Data.Entity.Migrations.DbMigrationsConfiguration`1’ threw an exception.” Só que este erro é muito generico e não encontrei muitos materias que me explica-se o pq do problema.
    Desde já agradeço a atençao

    • Fala Ricardo!

      Muito obrigado pelo feedback!
      Abaixo desta mensagem existe mais detalhes sobre o erro, precisaria saber qual que é para lhe ajudar.

      Abs!

      • Boa tarde Eduardo! Muito boa aula… Parabéns pelo tema e pelas dicas!! Tive o mesmo problema que o Ricardo no package… olhei no object browser e não tinha a referência DbMigrationsConfiguration, será que pode ser este o problema? Sem mais, agradeço a atenção.

        PM> Enable-Migrations -Verbose
        Using StartUp project ‘ehDiario.MVC’.
        Using NuGet project ‘ehDiario.Data’.
        Checking if the context targets an existing database…
        System.TypeInitializationException: The type initializer for ‘System.Data.Entity.Migrations.DbMigrationsConfiguration`1’ threw an exception. —> System.TypeInitializationException: The type initializer for ‘System.Data.Entity.Internal.AppConfig’ threw an exception. —> System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize —> System.Configuration.ConfigurationErrorsException: Only one element allowed per config file and if present must be the first child of the root element. (F:FontesDiarioEletronicoeh!DiarioehDiarioehDiario.MVCtmp47E.tmp line 13)
        at System.Configuration.ConfigurationSchemaErrors.ThrowIfErrors(Boolean ignoreLocal)
        at System.Configuration.BaseConfigurationRecord.ThrowIfParseErrors(ConfigurationSchemaErrors schemaErrors)
        at System.Configuration.BaseConfigurationRecord.ThrowIfInitErrors()
        at System.Configuration.ClientConfigurationSystem.EnsureInit(String configKey)
        — End of inner exception stack trace —
        at System.Configuration.ClientConfigurationSystem.EnsureInit(String configKey)
        at System.Configuration.ClientConfigurationSystem.PrepareClientConfigSystem(String sectionName)
        at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
        at System.Configuration.ConfigurationManager.GetSection(String sectionName)
        at System.Configuration.ConfigurationManager.get_ConnectionStrings()
        at System.Data.Entity.Internal.AppConfig..ctor()
        at System.Data.Entity.Internal.AppConfig..cctor()
        — End of inner exception stack trace —
        at System.Data.Entity.Infrastructure.DependencyResolution.DbConfigurationManager.EnsureLoadedForAssembly(Assembly assemblyHint, Type contextTypeHint)
        at System.Data.Entity.Infrastructure.DependencyResolution.DbConfigurationManager.EnsureLoadedForContext(Type contextType)
        at System.Data.Entity.Migrations.DbMigrationsConfiguration`1..cctor()
        — End of inner exception stack trace —
        at System.Data.Entity.Migrations.DbMigrationsConfiguration`1..ctor()
        at ehDiario.Data.Migrations.Configuration..ctor() in f:FontesDiarioEletronicoeh!DiarioehDiarioehDiario.DataMigrationsConfiguration.cs:line 10
        — End of stack trace from previous location where exception was thrown —
        at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
        at System.Data.Entity.Migrations.Utilities.MigrationsConfigurationFinder.FindMigrationsConfiguration(Type contextType, String configurationTypeName, Func`2 noType, Func`3 multipleTypes, Func`3 noTypeWithName, Func`3 multipleTypesWithName)
        at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.FindConfiguration()
        at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldRunner.Run()
        at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
        at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
        at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
        at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldInitialCreate(String language, String rootNamespace)
        at System.Data.Entity.Migrations.EnableMigrationsCommand.c__DisplayClass2.b__0()
        at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
        The type initializer for ‘System.Data.Entity.Migrations.DbMigrationsConfiguration`1’ threw an exception.

  14. Parabéns pela iniciativa Eduardo.

    É o melhor conteúdo sobre Asp.net MVC e Arquitetura em português que temos em nossa comunidade, sem mais.

    Parabéns pela iniciativa, espero que todo conhecimento que você passa para quem te acompanha possa te dar tudo em dobro na sua vida.

    Agora fica uma grande dúvida.

    O Asp.net Identity, entra em qual camada? Domain(Service)? Aonde exatamente?

    Outra coisa que notei, foi o uso de IEnumerable, haveria muito impacto ao mudar para IQueryable? levando que ele tem maior performance que IEnumerable

    • Fala Rodrigo!

      Muito obrigado pelo feedback!

      Identity fica em Infra > CrossCutting > Identity

      Eu prefiro IEnumerable e usar outros apenas em caso de real necessidade.

      Abs!

    • Esta pasta é para refletir o modelo proposto pelo DDD

      Nela vc pode incluir serviços REST, WebServices e outros serviços ( que não sejam domain services, isso é outra coisa )

      Abs!

  15. Eduardo, primeiramente, parabéns pelo post. Fiquei com uma dúvida apenas sobre a função da camada de App.

    Se os serviços invocam as operações do repositório, posso aplicar as regras antes da persistência. Então o que eu faria na camada de App?

    Tenho lido muitas coisas à respeito, mas ainda não encontrei um exemplo concreto.
    Se a camada de apresentação conhece o domínio, porque não acessar seus serviços diretamente, principalmente quando as operações são elementares, tipo:

    Controller.Save(obj) > App.Save(obj) > Serv.Save(obj) > Repo.Save(obj)

    • Fala Lano!

      Muito obrigado pelo feedback!
      Na Application vc pode controlar Unit of Work, Log, Converter Models em ViewModels etc.

      Esse é um exemplo bem simples, no caso de um projeto com N funcionalidades essa camada é bem útil.
      Sugiro a leitura do livro do Erick Evans sobre DDD.

      Abs!

  16. Boa tarde,

    Parabéns pela iniciativa. Tenho uma questão de um potencial problema na sua arquitetura:

    – O Entity Framework já implemente por si o Repository Framework e o Unit of Work.

    – Ao criar um Repositório genérico que é na verdade uma abstração do DBContext, estamos a criar um novo DBContext por cada Repositório que é chamado abrindo assim múltiplas ligações à base de dados no que poderia ser uma única transação tal como acontece utilizando por defeito o Db Context do Entity framework.

    – Isto acontece porque em cada repositório irá ocorrer a linha protected ProjetoModeloContext Db = new ProjetoModeloContext(); do repositório base…

    – Tudo bem que o DDD seja a favor da separação (sebem que a unica vantagem que vejo é permitir TDD no repositório pois poderia usar o IDbSet como repositório), mas se vai separar deve implementar um Unit of Work para as transações implementando pelo menos um commit e um saveChanges!

    Com o código como tem mais vale utilizar diretamente o Entity Framework, utilizando assim o padrão Unit of Work e evitando a complexidade adicional de cirar uma abstração de uma abstração.

    Reveja este ponto (acrescentando um Unit of Work na sua arquitetura e aí sim, este projeto terá mais valor e será uma arquitetura de referência!)

    • Olá Fonsini

      Exato, esse é um modelo para apresentar como se faz uma arquitetura em DDD, porém faltou o UoW e a forma de criar o contexto no repositório pode ser melhorado.

      A ideia neste caso não foi criar uma arquitetura de referência, apenas clarear como as coisas devem ser separadas, o vídeo já ficou muito extenso, pretendo lançar outro complementando e aí sim finalizar entregando uma arquitetura de referência.

      Abs.

  17. Eduardo, como vai?

    Só consigo utilizar essa aplicação no meu localhost. Quando envio para o servidor de hospedagem, ele retorna erro de permissão. Todos os servidores hoje trabalham com trust level medium, e esse tipo de asp.net mvc com EF exige trust level full. Quando coloco medium no web.config nem o localhost funciona. Você acha que isso será um problema quando as pessoas começarem a utilizar essa tecnologia em servidores comuns?

  18. Eduardo, meus parabéns por esse valioso post sobre DDD. Você tem uma ótima didática e demonstra domínio sobre o assunto. Gostaria que você fizesse mais artigos nesse nível.
    Um grande abraço!

  19. Quero agradecer por disponibilizar este material muito interessante para aqueles que estão aprendendo a programar, como eu. E aproveitar para tirar uma dúvida: Na sua arquitetura de pastas na solução, o que seria colocado na pasta 1-service? Tive olhando em outro projeto que (Estrutura dos Projetos: Core, Data e Service), nele o domínio está em Core, e em Service (outro projeto) está os mesmos serviços que no seu exemplo esta na pasta Domínio/service Ex: clientes.Where(c => c.ClienteEspecial(c). Então está é minha dúvida, quais serviços seriam colocados em um projeto separado? Desde já, Muito Obrigado!!! 🙂

    • Fala Reinaldo!

      Muito obrigado pelo feedback!
      Os services são serviços REST, WebServices e etc…

      Os serviços de domínio são outra coisa, eles ficam em Domain mesmo e não devem ser separados.
      Abs!

  20. Vídeo sensacional! Parabéns e obrigado, Eduardo Pires, por compartilhar gratuitamente um conteúdo desse nível.

    Vou aplicar esse arquitetura em um projeto novo que surgiu na empresa, já passei o vídeo para equipe assistir. hehehe

    Podes me tirar uma dúvida?! No finalzinho do vídeo você adiciona uma referência da Infra.Data no projeto MVC, para resolver o IoC, porém você ressalta que não deve ser assim, que o correto seria criar um outro módulo. Não entendi o que você quis dizer com módulo, seria um outro projeto “ProjetoModeloDDD.IoC” e referenciaria ele no projeto MVC?

    • Olá Felipe,

      O Identity é ferramenta, ele deve ir para Infra, algumas coisas vão ficar presas na apresentação ainda, mas dá para dar uma boa isolada.

      Abs!

  21. Fala Eduardo, muito bom o vídeo, parabéns!

    Fiquei com 2 dúvidas:

    – Onde entraria um projeto de Web Api nessa arquitetura?

    – Você tem alguma referência de como isolar o módulo para inversão de controle (que vc comentou) para que a camada de UI não faça referência ao projeto de Infra?

    Valeu!

  22. Eduardo excelente tutorial. Parabéns mais uma vez. Comecei a estudar mais essa arquitetura e estou tendo um erro do tipo “The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects” quando tento incluir mais uma relação many-to-many. Para o repositório devo apenas passar os Ids das entidades e lá utilizando o mesmo conexto (Db) fazer as pesquisas e posterior inclusão?

  23. Olá parabéns pelo conteúdo, estou estudando DDD e achei bem didático!!!
    Estou fazendo alguns experimentos para aprender mais sobre EF, e não achei um meio de interagir dois DbContext em dois DataBase diferentes, no caso de uma falha no commit de um deles, fazer o rollback no outro. Saberia por onde procurar sobre o assunto. Procurei sobre Bounded Context e consegui fazer 2 DbContext em um banco. Desde já obrigado.

  24. Eduardo, parabéns pelo vídeo, desenvolvo com MVC a relativamente pouco tempo e seus artigos estão me ajudando muito. Estou com dificuldade de colocar o Ninject em um projeto separado, como você disse que seria o mais correto… eu preciso startar ele em algum lugar?
    Seria muito bom também se esta solution estivesse no github para ser melhorada e servir de referência para novos projetos utilizando o Pattern DDD
    Abç. Júlio

  25. Outra dúvida que surgiu foi na questão da publicação. Ao realizar a publicação para um IIS local apresenta a seguinte mensagem “No Entity Framework provider found for the ADO.NET provider with invariant name ‘System.Data.SqlClient’. Make sure the provider is registered in the ‘entityFramework’ section of the application config file”. Como o EntityFramework está na camada Infra.Data, como é a aplicação MVC vai reconhecer a existência do EF já que não existe no web.config da aplicação? Enfim, qual é a maneira correta de publicação? Devo instalar o pacote do EF na aplicação MVC?

    • Tudo bem Emerson.
      O problema que você está tendo é o seguinte: Como o projeto disponibilizado para download não possui uma “carga inicial” de banco de dados, você não possui o banco. Neste caso você deve ir no Package Manager Console do projeto Infr.,Data e dar um Add-Migration, desta forma será criada a carga inicial para seu banco de dados.
      Referente ao não possuir um Web.config, o que ocorre neste caso é que o seu Startup project é o MVC, desta forma a conexão com o banco de dados será lida do Web.config dele.
      Você pode inclusive alterar o data Source para que ele não pegue um localdb e crie um banco de dados diferente, as configurações da connectionString podem ser alteradas a vontade.
      Espero que eu tenha ajudado.

    • Emerson,

      Nesse caso sim, não é a melhor prática, dá para isolar, mas para isso as ViewModels devem ir para Application assim como o AutoMapper…

      Abs.

  26. Parabéns !

    Só fiquei com uma dúvida, qual a necessidade de ter a camada de serviço e a camada de aplicação… As aplicações que eu desenvolvi o Controller acessa diretamente a camada de serviço… O que eu faria na camada de aplicação ?

    • Vamos supor que o sistema tivesse uma lista de clientes interessados e m ser notificados via email que isso aconteceu, qual layer enviaria o email ? Application ou Service ? (olhando bem teus services não são bem uma “service layer” fazem parte da domain layer, mas então pra que servem ?)

      • Renato,

        As services são serviços do domínio, elas fazem coisas para as entidades, por ex, cadastrar algo no banco através do repositório.

        O envio de e-mail é Infra > CrossCutting

        Abs.

    • A camada de aplicação serve para gerenciar o UoW, gravar Log, gerenciar coisas que não devem ser feitas pela apresentação e muito menos pelo Domain.

      • Boa tarde Eduardo, show de bola esse tutorial!

        Pergunta, por acaso voce tem algum exemplo de gerenciamento de UoW na camada de aplicação? ou de algum site gringo mesmo? gostaria de entender como você imagina e implementa esse pattern. Obrigado. Se tiver algum trecho de código já fica mais claro, grato.

  27. Eduardo,
    Parabéns pelo tutorial. Estou estudando sobre esses assuntos e esse foi o vídeo mais completo que encontrei sobre o assunto! Gostaria muito de fazer o curso, porém como sou um desenvolvedor “independente”, infelizmente não tenho a verba necessária.
    Gostaria de fazer uma perfunta: quando vc usa o Ninject para fazer a injeção, na classe “NinjectWebCommon” (MVC), no método “RegisterServices”, vc realiza o Bind das interfaces de Repositório (logo vc faz a referencia de “Infra.Data” no projeto MVC, o que não é correto) e nesse momento vc diz que a maneira correta de fazer é a criação de um “módulo” para realizar essa injeção. O que seria exatamente esse “módulo”? Em qual camada deveria ficar a sua declaração?

  28. Tudo Bem Eduardo.
    Eu estava vendo seu tutorial e achei excelente. Parabéns, sempre procuro referências sobre arquitetura e a sua foi a melhor que encontrei.

    Fiquei apenas com uma dúvida. Gostaria de saber se você pode me esclarecer.

    Na camada de serviço temos as mesmas operações de CRUD da camada de repositório, onde tanto as interfaces de repositório quando as de serviços possuem as mesmas implementações. Como a origem e a base de tudo é o repositório, eu poderia neste caso, ao invés de escrever na interface IServiceBase todos os métodos de CRUD herdar de IRepositoryBase e aplicar a mesma regra para as demais classes, por exemplo. ServiceBase Herdar de IServiceBase e de RepositoyBase.
    Faço esta pergunta porque em algum momento pode existir um erro onde algo seja implementado no repositório e não seja implementado no serviço.

    Minha dúvida é:

    As classes e interfaces bases de serviço devem possuir os mesmos métodos CRUD das classes de Repositório? Se afirmativo é correto fazer o que eu sugeri acima em relação a herança das classes de repositório.

    Obrigado e novamente parabéns pelo excelente modelo apresentado.

    • Fala Eder!

      Muito obrigado pelo feedback!

      Até pode ser assim, mas ficaria muito acoplado, isso que apresentei é um modelo super básico, quando o sistema crescer as classes de serviços terão outros métodos, mais responsabilidades, com isso vc deve deixar o máximo desacoplado possível.

      Abs!

  29. Eduardo,

    Belo post.
    Só que estou com um problema ao inserir um novo registro. Segui os seus passo direitinho, só que no meu caso eu já tinha as tabelas criadas.
    Para cinsultar, editar e deletar funciona só para inserir que não, segue o erro abaixo.
    “An exception of type ‘System.Data.Entity.Infrastructure.DbUpdateException’ occurred in EntityFramework.dll but was not handled in user code” e “Cannot insert the value NULL into column ‘idProduto’, table ‘manServicos.dbo.tblProduto’; column does not allow nulls. INSERT fails.
    The statement has been terminated.”

    agradeço se poder ajudar.

    obrigado

  30. Eduardo, meus parabéns cara! O tutorial está de excelente qualidade, muito bem explicado e muito prático. Era o que eu estava procurando!!
    Que Deus continue te abençoando!

  31. Primeiramente mais uma vez parabéns pelo ótimo post
    Mas estou tendo um problema eu fiz a aplicação conforme seu vídeo e no fim tive a mensagem de erro “No Entity Framework provider found for the ADO.NET provider with invariant name ‘System.Data.SqlClient’. Make sure the provider is registered in the ‘entityFramework’ section of the application config file. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information”

    Ai fiz o download do seu código e tive exatamente o mesmo erro
    Só consigo rodar a aplicação se adicionar a referencia do Entityframework no projeto MVC como posso resolver isso ?

    • Acabei de ver que nos comentários anteriores você já respondeu que precisa copiar a DLL EntityFramework.SqlServer.dll parapasta bin da view
      obrigado

      • Cara, valeu por esse comentário “precisa copiar a DLL EntityFramework.SqlServer.dll parapasta bin” me foi muito útil. Eu estava com um problema que funcionava no ambiente de desenvolvimento e não funcionava no IIS, essa DLL é o que faltava e não estava referenciada.

        Muito obrigado

  32. Boa tarde Eduardo!
    Parabéns pelo excelente tutorial, já repassei para muitos amigos.
    Apenas uma observação, na criação do AutoMapper as funções das classes que criam o mapeamento não ficaram invertidas?

    DomainToViewModelMapping está criando um mapeamento ViewModel -> Domain e ViewModelToDomainMapping está criando um mapeamento Domain -> ViewModel…

    Abraços!

  33. Olá amigo Eduardo.

    Seu tutorial me deu mais base do que um monte de livros e exemplos que tentei aplicar, porem o caso dos módulos vi que você sugeriu para as pessoas o link https://github.com/ninject/Ninject/wiki/Modules-and-the-Kernel e vi que as pessoas ficaram com dúvidas de como impletar, inclusive vi pessoas em outros lugares pedindo ajuda para o seu proprio tutorial http://pt.stackoverflow.com/questions/38280/projeto-independente-inje%C3%A7%C3%A3o-de-dependencias-ninject
    Sei que seria um abuso pedir isso pra você, mas não teria como fazer só um passo a passo rapido… de como implementar o ninject como modulos?

    Mais uma vez muito obrigado.

    Abs,
    Paulo Lima

  34. Eduardo,
    Parabéns, pelo artigo, realmente muito bem explicado e didático.
    Me ficou uma dúvida: Eu trabalho com uma arquitetura parecida, fiz algumas alterações mas mantive a essência devido a nossa realidade aqui no trabalho (nível da equipe, trocar pneu com o carro andando, etc).
    Tenho usado a camada de Aplicação para: Gravar os logs, orquestrar todas as interações e operações na camada de serviço do domínio e fazer o commit na UoW. Seria mesmo responsabilidade dela essas tarefas ?

    Obrigado pelo material.

    abs

  35. Boa Tarde.

    Por exemplo, se eu quero validar um campo duplicado na hora de inserir. Campo Nome do objeto cliente.

    Eu devo fazer no serviço de cliente na Domain ? E como eu retorno o erro para a presentation ? Por ValidationException ?

    Fiz assim e deu certo, mas não sei se é o correto:
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(ClienteViewModel model)
    {
    var clientedomain = Mapper.Map(model);
    if (ModelState.IsValid)
    {
    try
    {
    _clienteApp.Add(clientedomain);
    }
    catch (Exception ex)
    {
    ModelState.AddModelError(“”, ex.Message);
    ViewBag.Sexo = Dropdown.ddlSexo(model.Sexo);
    return View(model);
    }

    }
    return RedirectToAction(“Index”);
    }

  36. Eduardo, Bom dia !

    Seu tutorial é excelente, me ajudou basta a enter a arquitetura, agora eu tenho uma duvida parece besta, mas acho que é a duvida da maioria das pessoas.
    Bom, como eu teria que estruturar minha aplicação para consumir um WCF?
    no meu caso a camada de apresentação deve fica em um servidor separado de todo o resto, então todo o acesso a dados e regra de negocio devem ser feita através de serviços entendeu??
    vlw, e continue nos ajudando… 🙂

  37. Eduardo,

    Novamente esse seu post foi muito útil e vc está de parabéns.
    Tenho uma dúvida, de como usar o “Transaction Rollback” com o DDD, você teria uma dica ou um outro post que mostre como utilizar?

    obrigado e sucesso!!!

  38. Boa noite Eduardo Pires, Primeiramente quero agradecer pelo conteúdo do seu site. Está muito bom, você explica muito bem. Parabéns.

    Tenho uma dúvida referente à implementação da classe que registra os serviços no kernel (ninject).
    Eu fiquei na duvida se eu posso implementar na camada CrossCutting ou na propria camada de Dominio.
    Pelo que analisei acho que fica melhor na camada de Dominio criando uma interface Services e disponibilizar via injessão de dependencia para as outras camadas (Application e Presentation).
    O que acha?

    Obrigado.

  39. Olá Eduardo, tudo bem?
    Gostei de mais de sua vídeo aula e estou implementando este conceito em um projeto novo, porém me deparei um com problema que não consegui dar solução, pois tenho uma entidade que possui relacionamento com varias outras e alguma destas entidades filhas, possuem netas, e assim por diante. E eu gostaria de trazer todos os dados das filhas e netas através de includes, porém sempre recebo o seguinte erro:
    A specified Include path is not valid. The EntityType ‘NomeProjeto.Data.Context.EntidadePai’ does not declare a navigation property with the name ‘EntidadeFilha’.

    Como posso resolver isso?

  40. Boa noite, Eduardo.

    Parabéns e muito obrigado pelo conteúdo. Sempre excelente.

    Irei trabalhar num projeto multi-tenancy, e usarei seu material fazer deste, o meu primeiro projeto usando DDD.

    Gostaria de saber qual a forma mais saudável de assim que o usuário fizer o login, eu gravar qual o id da empresa dele, pois todas as consultas terão uma cláusula Where, setando o campo EmpresaId igual ao gravado no login.

    Muito obrigado, desde já.
    Um abraço

  41. Eduardo, Parabéns pelo tutorial.

    Tenho uma duvida quanto a camada de apresentação, como eu crio varias aplicações separadas por módulos com MVC exemplo: Financeiro e Estoque. Vc saberia me dizer como eu utilizo o conceito de HMVC (Hierarchical model–view–controller) no .net?

    VLW

  42. Boa Noite, Eduardo.

    Estou acompanhando o tutorial, achei muito bom, parabéns!

    Estou com problemas para criar a ClientesController, não tenho a opção Add -> Controller, somente Add -> WebApiControllerItemTemplate… Será que falta alguma referencia?

  43. Eduardo, boa noite.

    Consegui resolver o meu problema, mas não entendi o que aconteceu. Abri o projeto em uma versão express do VS e consegui criar a controller. (Add->Controller), pelo que percebi, era algo relacionado a criação do projeto.

    A única diferença que notei foi que ao selecionar o template MVC, o flag “Host in the cloud” estava desmarcado.

  44. Muita complexidade técnica desnecessária, excesso de engenharia, enquanto isso o cliente só quer resolver o problema com foco nos valores de Negócio e não brincar de DDD, camadas e mais camadas, Interfaces burocráticas e por ai vai. É difícil fazer o simples né?

      • O Eduardo já falou que o DDD é voltado à certos tipos de sistemas, não é aplicável em qualquer ambiente de desenvolvimento, muito menos para qualquer sistema.

        Embora ele tenha sido bem rude e ignorantão, haha, o comentário dele tem sim a ver.

        Pro sisteminha de locadora, realmente uma arquitetura DDD seria um “desperdício de tempo”, existem outras metodologias mais fáceis e mais práticas para projetos menos complexos; CQRS por exemplo.

        É uma questão de ver até onde seu sistema será escalonável e se o DDD será realmente útil ou não.

  45. Em primeiro lugar Parabéns Eduardo! Excelente iniciativa!

    Eu sou Arquiteto de Software e trabalho com .NET desde 2003.
    Já tive a oportunidade de criar e trabalhar com diferentes Arquiteturas.
    DDD é uma boa abordagem, mas não é “bala de prata” com qualquer outro padrão ou metodologia.

    Dúvidas!
    1) Você não acha interessante colocar suas Interfaces em outro Projeto dentro da mesma Solution Folder ? Dessa forma as camadas não terão Referência ao projeto onde estão as Classes Concretas. Porque com isso você previne que um desenvolvedor faça uma instância de uma Classe Concreta sem passar pela Injeção de Dependência.

    Só teriam referência ao Assembly de Interface.

    2) Eu fiquei com uma dúvida na sua Camada de “Application” !
    Ela seria apenas um “FAÇADE” ?
    O meu receio sempre de colocar essa camada e não expor diretamente os
    “Serviços” para a CONTROLLER seria acabar ficando um “BYPASS” onde uma camada chama outra sem realmente uma função definida…..acaba virando uma ARQUITETURA “CEBOLA”.

    Eu gosto de utilizar o FAÇADE para “ORQUESTRAR” os meus SERVIÇOS
    e fazer um Controle de Transação.

    Já trabalhei com o FAÇADE fazendo acesso ao Repositório e os SERVIÇOS
    só possuem realmente “REGRA DE NEGÓCIOS”.

    3) Onde você coloca o seu Controle de Transação ?
    Utiliza o System.Transctions ?

    4) Costuma utilizar o padrão SINGLETON ? Onde ???

    OBRIGADO ! E PARABÉNS MAIS UMA VEZ !

    GRANDE ABRAÇO
    LÉO

  46. Eduardo,

    Sempre acompanho seus post são excelentes. Didática simples e de fácil compreensão. Parabéns pela iniciativa.

    Estava estudando este tutorial mais a fundo e tive uma dificuldade. Preciso criar um cadastro de Cliente com seu Endereço mas eu preciso criar na mesma view. Criei uma ViewModel. Mas eu não consigo fazer o CRUD separado dados de Cliente e dados de Endereço cada um em suas respectivas tabelas. Tem algum post ou alguma dica sobre este assunto? Como poderia aplicar da melhor forma e maneira esta situação neste modelo?

    Obrigado!

  47. Eduardo antes de mais excelente artigo, está a servir de base para o desenvolvimento de uma arquitectura.

    Depois de ter lido muita coisa sobre DDD, existe uma situação na sua arquitectura que não bate certo.

    Voce coloca todas as acções relacionadas com as entidades de Dominio em DomainServices e deixa as Entities como POCO’s, isto não segue a abordagem DDD, em que as Entities têm comportamento e os DomainServices apenas contêm o comportamento que é transversal a várias entidades.

    No caso da sua arquitectura, voce coloca os métodos CRUD em DomainServices, já para não falar nos outros princicpios de DDD como Value Objects.

    Estou um pouco confuso em relação a sua variação de DDD, pode clarificar porque não arrumou as coisas nas Entities.

    “When a significant process or transformation in the domain is not a natural responsibility of an ENTITY or VALUE OBJECT, add an operation to the model as standalone interface declared as a SERVICE. Define the interface in terms of the language of the model and make sure the operation name is part of the UBIQUITOUS LANGUAGE. Make the SERVICE stateless.

    Eric Evans Domain-Driven Design”

    http://gorodinski.com/blog/2012/04/14/services-in-domain-driven-design-ddd/

    • Ricardo, em DDD realmente Serviços de Domínio não têm nenhuma relação com CRUD, e estão corretas as outras coisas que você fala sobre Serviços de Domínio.

      Só uma observação: mesmo que suas Entidades tenham comportamento (o que é recomendado), elas não deixam de ser POCOs. POCOs não são a mesma coisa que classes anêmicas.

  48. Olá Eduardo, muito fera este video que vc fez !!
    Obrigado por compartilhar e ensinar os seus conhecimentos e
    publique mais videos de arquitetura 😉

  49. Bom dia!

    Estou seguindo esta aula, na classe de contexto (ProjetoModeloContext.cs), você sobrescreve o método SaveChanges, faz um foreach onde existe um “Where”. Estou com problema neste “Where” cara. Sou um pouco leigo ainda quanto a linguagem c#, A mensagem de erro é a seguinte: (‘System.Collections.Generic.IEnumerable’ does not contain a definition for ‘Where’ and no extension method ‘Where’ accepting a first argument of type ‘System.Collections.Generic.IEnumerable’ could be found (are you missing a using directive or an assembly reference?) C:UsersJonathanDocumentsVisual Studio 2013ProjetoCorretorProjetoCorretorProjetoCorretorDDD.InfraDataContextoProjetoCorretorContext.cs 37 52 ProjetoCorretorDDD.InfraData). Deste já agradeço a ajuda…

    • O objeto ao qual você está mandando receber os valores que vão retornar nessa query do Where, não é IENumberable, por isso está dando erro.

      • Para elucidar mais ainda : Funciona colocando “System.Linq” por que dentro desta biblioteca existem “extension methods”, ou métodos de extensão. Ao adiciona este novo using ai o “IENumberable” conhece este (where) e outros métodos.

  50. Excelente tutorial!

    Estava querendo aprender mais sobre DDD e ver como poderia ser útil aos projetos que desenvolvo, sem dúvida agora ficou claro, prevejo longas semanas de refatoração para um bem maior, mas empolgado com as possibilidades! 🙂

  51. Boa tarde Eduardo !! estou acompanhando seus tutoriais que por falar nisso e muito bom Parabéns !! , mas vendo este video de arquitetura , fazendo uns testes aqui o EF me criou as base de dados com a tabela cliente sem ter declarado o Dbset , isso aconteceu por causa da ClienteConfiguration ???? percebi isso quando fui criar a Dbset de produto , e possivel ou foi algun bug ?? seila !?.

  52. Olá Eduardo,

    Primeiramente parabéns pelo vídeo, certamente deu bastante trabalho produzi-lo, considerando sua extensão e a densidade do conteúdo.

    Tenho apenas uma observação e um questionamento:

    1 . Quando você fala sobre Value Objects, na verdade você dá a definição de Aggregate Root, quando Value Objects na verdade representam objetos que não possuem uma “identidade de longo prazo”.

    2 . Você implementou uma classe “ClienteAppService” na camada “Application” que possui um método para obter clientes especiais (regra de negócio), nestes casos eu geralmente criaria esse método como static dentro do “Domain.Entities.Cliente” para não precisar criar uma instância apenas para obter uma coleção de objetos de determinado tipo. Acha que essa é boa abordagem ou teria alguma desvantagem que não me atentei?

  53. Olá Eduardo,

    gostei muito do vídeo, apesar de assisti-lo com meses de atraso rsrsrs, mas antes tarde do que nunca, como dizia o “velho deitado”. Deixando a brincandeira de lado. Tenho uma dúvida sobre o NInject:
    Achei que na camada de apresentação, não fosse adicionado as referência de “Infra” ou que pelo menos fizesse um load da dll de infra e trabalhasse com ela. Deveria ser isso ou para dar continuidade ao video, vc adicionou para ser mais rápido e fácil?

    Acho que pode ser dificil do Eduardo ver meu comentário, então se alguém quiser me responder agradeço.

    abs e parabéns pelo vídeo!

  54. Pingback: Tenho um sistema legado e vou migra-lo, e agora?

  55. Olá Eduardo, parabéns pelo treinamento.
    Baixei o fonte, está vazio a pasta 1 – Services. O que seria nessa camada, teria algum documento?

    abs
    Marcos

    • Olá Marcos! Muito obrigado.

      Eu não fiz essa parte, nessa pasta você pode expor seu domínio através de serviços REST ou SOAP, dá uma olhada no diagrama para entender o conceito!

      Abs!

      • Olá Eduardo,

        Animal seu video, gostei bastante.

        Uma duvida:

        Eu pensei que meu domínio seria exposto via rest na camada APP, mas pelo seu comentário acho que estou errado.

        Se vou expor meu dominio via rest na camada de serviço, qual seria a responsabilidade da camada app?

        Obrigado e parabéns pelo seu trabalho.

  56. Ola Eduardo , gostei muito do vídeo bem explicado e didático estou iniciando com DDD, tenho uma dúvida estou desenvolvendo um sistema no qual o mesmo vai ser vendido para várias empresas posso reutilizar toda a estrutura dessa arquitetura, e trocar somente a camada de apresentação? E como eu repli

  57. Ola Eduardo , gostei muito do vídeo bem explicado e didático estou iniciando com DDD, tenho uma dúvida estou desenvolvendo um sistema no qual o mesmo vai ser vendido para várias empresas posso reutilizar toda a estrutura dessa arquitetura, e trocar somente a camada de apresentação? E como eu replicaria a atualização do sistemas para todas as empresas , sendo que cada uma possui suas próprias particularidades

    Abraço

  58. Falae Eduardo!

    Cara o treinamento foi animal, fiz em junho e somente agora estou podendo voltar a mexer com tudo que você passou. E com isso surgiu uma duvida que não vi nos videos. Como fica a persistência de um novo Endereço no caso daquela arquitetura que você passou ? O que percebi é que como a tabela ClienteEndereco não é mapeada não há como gravar apenas o endereço pela model Endereco, seria o caso de utilizar uma entidade associativa ? tem como mandar esse trecho de codigo como ficaria a persistência do endereço ?

    Obrigado

  59. Oi Eduardo,
    Acompanhei a vídeo aula: Tutorial ASP.NET MVC 5 + DDD + EF + AutoMapper + IoC + Dicas e Truques e gostei muito !!!
    Comecei um projeto, utilizando todo conceito do vídeo, mais quero saber como aninhar dois ou mais DropDownList?, utilizando a técnica utilizada na vídeo aula de DDD, Por exemplo, ao escolher um estado (UF) automaticamente atualizar a drop de cidades?

  60. Eduardo, parabéns pelo artigo muito bom! Gostaria de saber se os controllers eu posso colocar em um projeto separado da view e como a minha rota iria funcionar, valeu!

  61. Olá Eduardo. Estou seguindo o seu tutorial porém cheguei em um problema que não consegui resolver. No momento de configurar o AutoMapper, na classe DomainToViewModel, quando tento sobrescrever o método Get do ProfileName ele me gera um erro dizendo que o método não pode ser sobrescrito. Mesmo copiando a classe do projeto ele continua dando este mesmo erro. O AutoMapper que estou usando está na versão 4. Saberia dizer se nesta versão tem algo diferente neste caso?

    • Olá, tive o mesmo problema. Parece que na versão 4 do AutoMapper, mudou a forma de implementar a classe, e não se usa mais o override dos métodos. Eu resolvi usando o construtor, passando o mesmo valor string da propriedade ProfileName no construtor base(“…”)
      Ex:
      public DomainToViewModelMappingProfile()
      : base(“ViewModelToDomainMappings”)
      {

      }

  62. Boa tarde, adorei o tutorial!
    Gostaria de saber se você tem algum tutorial ou link prático para fazer o migrations utilizando mysql. Consegui fazer, mas quando vou mapear a chave estrangeira e unique key dá erro de sintaxe.

    Att.

  63. Olá Eduardo.

    Show de bola o video. Parabéns.

    Eu tenho uma dúvida mas é mais conceitual. Nesse modelo DDD, o domínio é responsável pelas entidades e inclusive pelas interfaces do repositório. Ou seja, é ela quem manda o que terá ou não no banco de dados inclusive. Sendo que na camada de repositório tem apenas configurações do que tem no domínio, é realmente necessário essa camada? Pergunto porque me parece que, ao menos, nesse exemplo, a Infra.Data é quase uma extensão da domínio. O ORM, no meu caso EF, já não seria minha camada de repositório?

    Vlw. Abraço.

  64. Olá Eduardo, antes de mais nada, você tem uma material excelente, está de parabens! Agora vem minha dúvida, estou seguindo o tutorial, porém fiquei trancado na parte do AutoMapper, vi que você escreveu que apenas não era para dar override, porém removi o código do override e ao entrar na lista e chamar o GetAll(), ele da o seguinte erro: (Importante ele ocorre ao cadastrar o primeiro cliente, pois quando não havia nada cadastrado ele funcionava, ai então ao cadastrar e voltar para index apresenta a mensagem)

    {“Missing type map configuration or unsupported mapping.rnrnMapping types:rnCliente -> ClienteViewModelrnProjetoDDD.Domain.Entities.Cliente -> ProjetoDDD.MVC.ViewModels.ClienteViewModelrnrnDestination path:rnIEnumerable`1[0]rnrnSource value:rnProjetoDDD.Domain.Entities.Cliente”}

    • Olá Wagner, valide se você mapeou nos dois sentidos ViewModel > Domain e Domain > ViewModel. Valide se registrou o Automapper no Global.asax, Valide se as propriedades são exatamente compatíveis.

      Abs.

      • Bom dia Eduardo, obrigado pela resposta, dei andamento no tutorial e mesmo assim continuei com o mesmo problema, depois verificando as mensagens que o VS estava exibindo encontrei como resolver, tive que fazer o mapa reverso dessa forma:

        Mapper.CreateMap().ReverseMap();
        Mapper.CreateMap().ReverseMap();

        Assim resolveu a exception que estava ocorrendo.

        Obrigado!

  65. Boa tarde,
    Primeiramente, Parabéns pelo vídeo, ótima didática!
    Eu estou começando na área de desenvolvimento e tenho assistido alguns videos seus, uma coisa que me deixou um pouco confuso neste vídeo, se vc criar uma entidade e adicionar adicionar vários métodos, não estará ferindo o S do S.O.L.I.D?

    • Boa noite,

      Sei que não foi para mim, porem acredito que posso ajudar.
      li um livro que fala sobre SOLID e OO.

      Bom o S do solid é que as classes devem ser coesas, ou seja, terem uma única responsabilidade. Classes assim tendem a ser mais reutilizáveis, mais simples, e propagam menos mudanças para o resto do sistema.

      E a composição de um objeto tem atributos e comportamentos.

      Logo a ideia é você não criar uma classe anêmica… essa classe deve ter apenas um motivo para ser alterado, e isso engloba os comportamento dessa classe.
      Acredito, me corrijam se eu estiver errado, que o exemplo citado não desobedece essa regra.

  66. Eduardo excelente material e iniciativa de compartilhar seu conhecimentos.. Apenas umas duvida, ainda sobre IoC, apos criar um novo projeto na infra CrossCutting, criei uma classe modulo abrangendo os bind, no exemplo da pagina que nos passou ela é consumida dentro do metodo Main() de um console application, como ficaria isso dentro do projeto que vc criou ? dentro do RegisterServices() ou dentro da Cotroller, procurei na net é só achei exemplos de utilização na Main().
    Obrigado pela ajuda.

    Abs

  67. Parabéns pelo tutorial, ótima iniciativa. Tenho uma dúvida. Ao invés de colocar as validações na ViewModel do MVC, poderia colocar nas entidades do Domain para poder reaproveitar as validações para outro tipo de projeto?

    • Fala Osorio, sei que a pergunta não foi pra mim mais essa acho que posso te ajudar. Você pode sim incluir as suas validações dentro da camada de Domínio, porem isso não te isenta de inclui-las dentro da ViewModel, visto que essas validações estão totalmente relacionadas com a tecnologia usada na camada de apresentação (Interface Grafica) de cada projeto (Web, Mobile,etc..). Bom acho que é isso, se eu estive errado, me corrijam.
      Abs.

  68. Pingback: Cuide bem do seu domínio! Parte 1 | Alexandre Miranda

  69. Pingback: Cuide bem do seu domínio! Parte 3 | Alexandre Miranda

  70. Boa tarde Eduardo!
    Estou com um problema que parece ser basico, mais não estou conseguindo entender o porque eu não tenho a opção de criar class no visual studio 2015, quando eu clico em Add, no visual studio 2012 ele tem essa opção. O visual studio é 2012 é ultimate o 2015 é profissional.
    Pode ser isso?

  71. Olá!
    Excelente tutorial.
    Eu estou começando na área de desenvolvimento web.
    Gostaria de saber se dará continuidade ao mesmo tutorial. Vi que faltou as consultas de produtos por nome. Estou encontrando dificuldades.

  72. Boa tarde Eduardo,

    Ótimo vídeo! curti a divisão da estrutura, mas fiquei em dúvida com o papel de cada camada!
    Seria tipo isso?

    0 – Presentation
    Camada de apresentação (MVC, WebApi, WPF, etc)
    1 – Services
    Aqui ficariam serviços independentes? (Webservices e etc)
    2 – Application
    Regras de negócio da aplicação
    (Exemplo: em um sistema financeiro, para se executar a rotina de “saque” envolvemos vários objectos e suas propriedades)
    3 – Domain
    Definição das classes de dominio e suas propriedades individuais
    4 – Infra
    4.1 – Data
    Respositorio de dados
    4.2 – Cross Cutting
    Aqui ficariam as bibliotecas de uso geral do sistema?

    Em que nível estariam os testes unitários?
    Caso tenha falado alguma besteira na responsabilidade de cada nível, peço que corrijam e deem algum exemplo mais prático, se possível.

    Valeu galera!

    • Boa noite,

      Bom olhando sua duvida eu gostaria de tentar responder, se permitido..

      0 – Presentation
      Camada de apresentação (MVC, WebApi, WPF, etc) . OK

      1 – Services
      Olhando o video ficou um pouco obscura para mim, mas dando uma googlada lendo outros artigos e revendo o video umas 5 vezes, deu a entender que essa camada é responsável por regras de negocio que não pertence a uma entidade especifica.
      Sendo tratada como Serviço (acredito que o mesmo conceito do SOA)

      2 – Application
      essa camada não possui lógica de negócio. Ela é apenas uma camada fina, responsável por conectar a camada de apresentação às camadas inferiores

      3 – Domain
      Definição das classes de dominio e suas propriedades individuais;
      Aqui você coloca as regras de negocios que pretence a entidade, como no exemplo do video, “usuario especial”

      4 – Infra
      4.1 – Data
      Respositorio de dados
      E/OU Web services…
      No caso se você tem algum recurso a ser consumido externamente ela deve estar nessa damada de ACESSO A DADOS (banco de dados relacional, não relacional, webservices e acredito que até acesso a arquivo em diretorios local ou da rede(ftp, tcp ip e etc) )

      4.2 – Cross Cutting
      Aqui ficariam as bibliotecas de uso geral do sistema.
      Coisas que atravessa a arquitetura. ou seja elas não precisa seguir a hierarquia da arquitetura.

      Em que nível estariam os testes unitários?
      Se estiver falando de TDD…. isso não se enquadra na categoria “arquitetura”. é uma maneira de você escrever o codigo testando ele primeiro e corrigindo os erros que por obrigação devem aparece na usa implementação…
      Caso seu teste unitário não ocasionar erro, logo não tem oque ser alterado.

      Bom espero que não tenha falado “groselhas” e tbm espero que eu tenha acertado, pois estou estudando muito arquitetura, e esta no meu radar compreender de inicio o DDD e SOA, e os conceitos de solid, ioc, Orientação Objeto (a ideia disso é bem complexa, parece simples mas não é O_o) clean code e etc..

  73. Bom dia, Parabéns pelo video muito bom para quem esta começando e querendo aprender padrões de desenvolvimento, segui fielmente seu tutorial justamente por querer entender mais dos projetos em mvc com tudo usei em algumas telas para mesclar dados o EditorTemplates e percebi que existe uma certa dificuldade para atualizar dados com Pais e Filhas das entidades Filhas ou mesmo das Pais quando estamos trabalhando com ela como entidade principal li alguns tutoriais e encontrei um artigo falando escrito em que se critica a abordagem com AutoMapper https://rogeralsing.com/2013/12/01/why-mapping-dtos-to-entities-using-automapper-and-entityframework-is-horrible/#comment-14008, acredito que esse não seja o meu problema porque no retorno do meu objeto ViewModel eu tenho tudo preenchido de acordo com oque foi alterado na tela o problema é que o EntityFramework 6 só entende um objeto como sendo para alterar parece que ele não esta considerando os objetos do EditorTemplates isso após as alterações serem feitas como uma entidade para ser alterada existente no contexto é como se ele tivesse perdido ela no retorno bem como é previsto no MVC.Como posso resolver isto e fazer ele entender que minhas entidades filhas precisam ser alteradas no padrão DDD.

  74. Olá Eduardo!

    Sei que o post é antigo, mas gostaria de parabenizar por todo o trabalho que compartilha conosco.
    No entanto, gostaria de uma ajuda: Estou desenvolvendo uma aplicação pequena, mas resolvi fazer igualmente ao tutorial apresentado, mas estou com um problema nas Actions Edit e Delete. Já olhei o código diversas vezes e está igualzinho o seu, mas ao chamar as actions citadas apresenta o seguinte erro: The parameters dictionary contains a null entry for parameter ‘id’ of non-nullable type ‘System.Int32’ for method ‘System.Web.Mvc.ActionResult Edit(Int32)’ in ‘appXXX.Presentation.Controllers.XXXController’. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
    Nome do parâmetro: parameters
    O que estou observando é que, por algum motivo que ainda não consegui identificar, o parametro “id” nas actions citadas está retornando nulo. Poderia me ajudar? Me dá uma luz?

    Obrigado.

      • Obrigado pela atenção. Vou postar aqui parte do código correspondente:

        NO DOMAIN

        public interface IRepositoryBase where TEntity : class
        {
        IEnumerable GetAll();
        TEntity GetById(int id);

        }

        public interface IServiceBase where TEntity : class
        {
        IEnumerable GetAll();
        TEntity GetById(int id);

        }

        public class ServiceBase : IDisposable, IServiceBase where TEntity : class
        {
        private readonly IRepositoryBase _repository;

        public ServiceBase(IRepositoryBase repository)
        {
        _repository = repository;
        }

        public TEntity GetById(int id)
        {
        return _repository.GetById(id);
        }

        public IEnumerable GetAll()
        {
        return _repository.GetAll();
        }


        }

        NO INFRA

        public class RepositoryBase : IDisposable, IRepositoryBase where TEntity : class
        {
        protected AppContext context = new AppContext();

        public TEntity GetById(int id)
        {
        return context.Set().Find(id);
        }

        public IEnumerable GetAll()
        {
        return context.Set().ToList();
        }


        }

        NO APPLICATION

        public interface IAppServiceBase where TEntity : class
        {
        IEnumerable GetAll();
        TEntity GetById(int id);

        }

        public class AppServiceBase : IDisposable, IAppServiceBase where TEntity : class
        {
        private readonly IServiceBase _serviceBase;

        public AppServiceBase(IServiceBase serviceBase)
        {
        _serviceBase = serviceBase;
        }

        public TEntity GetById(int id)
        {
        return _serviceBase.GetById(id);
        }

        public IEnumerable GetAll()
        {
        return _serviceBase.GetAll();
        }

        }

        NO CONTROLLER

        private readonly IxxxAppService _xxxApp;

        public xxxController(IxxxAppService xxxApp)
        {
        _xxxApp = xxxApp;
        }

        // GET: xxx/Edit/5
        public ActionResult Edit(int id)
        {
        var xxxDomain = _xxxApp.GetById(id);
        var xxxViewModel = Mapper.Map(xxxDomain);

        return View(xxxViewModel);
        }

        //POST: xxx/Edit/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(xxxViewModel _xxx)
        {
        if (ModelState.IsValid)
        {
        var xxxDomain = Mapper.Map(_xxx);
        _xxxApp.Update(xxxDomain);

        return RedirectToAction(“Index”);

        Como pode ver tudo igual ao seu exemplo. Mas aí na execução, quando clica no no item, a Action Edit não é chamada pq o id retorna nulo.

        A Action de Create funciona e a função GetAll() tbm. O problema mesmo é com o Edit e consequentemente com o Delete tbm. Não consigo perceber o que tem de errado.

        Obrigado pela atenção.
        }

        return View(_xxx);
        }

  75. Boa noite,

    Primeiramente, parabéns pelo post/vídeo muito bom, da pra entender bastante coisa.

    Fiquei com uma duvida que esta me consumindo, sobre a camada de dados e de apresentação.

    No video você fala que a camada de apresentação não precisa visualizar a camada de acesso a dados.

    Porem quando você fez a injeção de dependência teve que referenciar a camada de acesso a dados…
    Você tbm disse que poderia isolar em modulo …

    Minha duvida é COMO?
    Não estou conseguindo abstrair essa ideia e implementar no código.

    Desde já agradeço a atenção.

    • Olá Alison!

      Seguindo com Ninject você pode utilizar uma classe de Module! Se for com outros injetores cada um tem uma maneira parecida.

      Abs!

  76. Eduardo parabéns pelo vídeo está ótimo.

    Gostaria de tirar uma dúvida, como ficaria esse projeto se utilizar WPF no cliente e Webservice no servidor? Acabei de seguir o vídeo, mas ficou meio confuso para mim como separar essa arquitetura.

  77. Muito bom o vídeo Eduardo, bem simplificado, bem segmentado e bem explicativo!
    Com certeza verei mais seus!
    Apenas tive um pequeno problema com este projeto e ficaria muito grato se você me ajudasse com a situação para que eu tenha um melhor aprendizado.
    Na classe “ClienteAppService” e na “ProdutoAppService” está com erro no construtor das respectivas classes. Ele me da o erro que não consegue converter “clienteService” e “produtoService”. Desta forma acaba sendo impossivel de executar o construtor da AppServiceBase! O erro que dá em ambas classes é:
    “cannot convert from ‘ProjetoModeloDDD.Domain.Interfaces.Services.IClienteService’ to ‘ProjetoModeloDDD.Application.Interface.IApp.ServiceBase'”

    Fico no aguardo e parabéns pela as aulas, realmente são boas!!
    Gabriel

    • Provavelmente as classes construtoras estao “private” mude para “public”. Também tive esse erro e depois de algumas horas acabei descobrindo isso.

  78. Olá Eduardo boa tarde, você utiliza o AutoMapper no seu tutorial, porém essa forma já esta “obsoleta”, gostaria de saber qual a forma “correta” de utiliza-lo na versão 4.2 em diante, pois será retirado da versão 5.0 (provavelmente já foi retirado, pois a versão 5.0 já esta disponível).

  79. Olá!

    Uma dúvida:
    Eu tenho um formulário de cadastro de produtos e preciso salvar os dados do produto e uma imagem. Em qual camada você utiliza para salvar a imagem no servidor ?

  80. Ola Eduardo!
    Uso a mesma abordagem em um projeto pessoal e tive problemas com a LocaWeb na hora de hospedar o sistema.
    Recebo um erro referente ao ninject ao Trust level do servidor deles.
    Não encontrei nenhuma informaçõa relevente sobre o Ninject funcionar com Trust Level Medium (Requerido pela LocaWeb). O que posso fazer nesse caso? Trocar o container?

  81. Eduardo, boa tarde!

    Parabéns pelo material muito rico e didático! Gostaria de pedir o código fonte e de tirar uma dúvida.

    O projeto de apresentação teria referência somente ao Domínio e CrossCutting
    O projeto de Aplicação teria referência somente ao Domínio e CrossCutting
    O projeto de Data teria referência somente ao Domínio

    Domínio e CrossCutting são limpos.

    Está correto?

    Muito Obrigado!

  82. Olá Eduardo,
    Parabéns pela aula.
    Mas gostaria de tirar 2 dúvidas:
    – Por que os Contratos dos Repositories foram criados na camada de Domain, e não na própria camada de Infra?
    – olhando para a estrutura criada, a camada Application é necessária? Vejo que ela simplesmente replica o código do seu Domain. Entendo que mesmo sem ela, os conceitos de SOLID ainda estão mantidos.
    Entendi algo errado?
    Abraços.

  83. Cara, parabéns por compartilhar o seu conhecimento! Todos os seus artigos são muito úteis e muito bem feitos! Você faz os artigos com muito zelo! Estou me preparando (pré-requisitos) pra fazer o seu curso de MVC e não vejo a hora! Parabéns e obrigado!

  84. Boa noite Eduardo,

    Parabéns pelos vídeos postados, tem ajudado bastante. No final, logo após adicionar o ninject, quando está adicionando as referências na classe “NinjectWebCommon” você diz que deveria ter criado um modulo para evitar fazer a referência a “Infra.Data.Repositories”.
    Poderia me dar um exemplo de como fazê-lo?
    E pra que serve a pasta: “1 – Services”?

    Desde já agradeço a atenção

  85. Parabéns Eduardo, lançou uma luz sobre minhas dúvidas sobre a arquitetura DDD. Muito bom mesmo, você explica de maneira simples e direta, qualquer iniciante pode entender bem o que você está falando. Bom, gostaria que quando puder, você fazer algum vídeo sobre o Asp.Net Core.
    Valeu!

    Abs.

  86. Boa tarde Eduardo

    Sobre mobile, principalmente me casos que usamos MVVM, essa arquitetura se encaixa e com quais alterações?

    No MVVM já temos uma View Model, ficando a Model como parte do Domain e implementar as demais camadas.

    Obrigado

  87. Boa tarde,

    Tenho uma consulta com uma pivot table dynamic (que poderar me retornar 4, 5 ou mais campos) e gostaria de saber se é possível criar uma entidade para a mesma?

  88. Estou começando a estudar asp.net e estou curtindo muito, espero aprender a desenvolver e graças a vídeos como este que dinamizam ainda mais nosso aprendizado, parabéns pelo excelente conteúdo.

  89. Olá Eduardo!

    Parabéns pela iniciativa! por mais um conteúdo de qualidade e contribuição a comunidade, estou começando estudar recentemente, também leio os comentários aqui postado, suas respostas, e isso tem ajudado a esclarecer ainda mais o conceito! Encontrar a abordagem completa deste tema com detalhes é algo difícil e desenvolver com qualidade é algo essencial que infelizmente nem toda empresa prioriza.

    Abraço!

  90. Olá Eduardo, parabéns pelo tutorial. Realmente me ajudou muito.

    Fiquei curioso com um detalhe, o atributo “Ativo” da tabela “Clientes” poderia ser filtrado no DbContext, assim como é feito o Set no campo “DataCadastro”, de modo que os métodos do RepositoryBase (GetById ou GetAll) não precisem ser modificados? A ideia seria apagar os registros de forma lógica.

    Você tem alguma recomendação?

  91. Oi Eduardo. Primeiramente parabéns pelo post. Muito bom e muito instrutivo.

    Com relação ao projeto, como eu implementaria a questão da segurança? Fazendo autenticação de usuários e utilizando WebAPI?

    Obrigado.

  92. Olá Eduardo,

    Uma questão sobre o DDD… Estou implementando a estrutura num projeto com banco de dados legado. Por conta disso, não posso fazer pelo caminho do code-first, mas sim database first.

    Por ser database first, acabo seguindo uma linha diferente de configuração do meu projeto data, tendo de apontar o banco de dados e criando um estrutura de arquivos associados a um .edmx, onde nele estão as classes que mapeiam o banco.

    Percebo que seguindo esse formato, minha estrutura de pastas na verdade se resume apenas a uma pasta (context), pois o VS transforma tudo numa única estrutura, e não tenho como criar separadamente as classes de entidades, separando do arquivo DbContext.

    Como você sugere a estrutura de pastas do projeto Infra.Data para esse caso ?

    Parabéns pelo vídeo e agradeço a ajuda.

    Atenciosamente,
    Marcelo de Oliveira

  93. uito bom esse material, pra quem está começando como eu é sempre bom ter material assim para estudos. Tenho um problema com a seguinte mensagem de erro: ‘Mapper’ does not contain a definition for createmap. estou usando Visual Studio Profissional 2015

  94. Eduardo, muito bom o tutorial!

    Gostaria de saber como posso criar uma conexão MySQL e trabalhar com Migrations conforme foi abordado no vídeo.

    Obrigado.

  95. Video aula MUITO bom. Mostrando todos os passos, sendo bem objetivo – mas sem atropelar as informações. Já tinha visto alguns videos, mas o seu foi o melhor. Parabéns.

  96. Eduardo, blz? Tudo bem?

    Como resolver o problema de referencia circular no AutoMapper?
    Exemplo: tenho a tabela Topicos que possui uma referencia para Categoria, porém ao retornar o registro através do EF, ele dá StackOverflow no AutoMapper.
    Consegui resolver desativando o Lazy Loading no context, mas daí sou obrigado a fazer um nova busca para pegar a lista de objetos filhos.
    Usando o MaxLength no Automapper tb nao resolveu.. =/

  97. Primeiramente parabéns pelo tutorial!!! ÓTIMO!
    Estou entrando neste mundo .NET agora, segui sua video aula e até ai tudo bem, porém add mais um projeto na minha solution do tipo WEB API… Criei a Model e a controler:

    public class CategoryController : ApiController
    {
    private readonly ICategoryAppService _categoryApp;

    public CategoryController(ICategoryAppService categoryApp)
    {
    _categoryApp = categoryApp;
    }

    public IEnumerable Get()
    {

    var categories = _categoryApp.GetAll();

    return (categories);
    }

    }

    Ao executar este código, recebo o erro: An error occurred when trying to create a controller of type ‘CategoryController’. Make sure that the controller has a parameterless public constructor.

    Implementei a solução do André Baltieri (https://weblogs.asp.net/andrebaltieri/dependency-injection-no-webapi), mas continuo tomando este erro.

    Codigo da WebApiConfig:

    public static void Register(HttpConfiguration config)
    {
    //DI
    var container = new UnityContainer();
    container.RegisterType(new HierarchicalLifetimeManager());
    config.DependencyResolver = new UnityResolver(container);

    Não sei se fui claro no problema, mas poderia ajudar?

  98. Fala Eduardo, tudo bem?
    Belo vídeo, gostaria de tirar uma dúvida, eu geralmente uso um projeto service, exemplo, ProjetoModeloDDD.Service e nele contem as classes concretas de serviço que você colocou no Domain, assim não uso um projeto Application, está errado desta forma?

    Obrigado,….

  99. Parabéns Eduardo pelo tutorial. Material excelente, o melhor que já vi nos últimos tempos. Já estou usando todos os fundamentos na criação dos meus novos projetos e com certeza, desejo aprofundar os estudos e vou fazer os seus cursos, iniciando pelo AspNet MVC5 e seguindo pelo de Arquitetura. Vou entrar em contato com você, inclusive para sondar a possibilidade do InCompany.

  100. Oi pessoal tive o tal do problema com o erro [
    “No Entity Framework provider found for the ADO.NET provider with invariant name ‘System.Data.SqlClient’. Make sure the provider is registered in the ‘entityFramework’ section of the application config file. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information”
    ]
    Nao entendi direito colei a dll
    (EntityFramework.SqlServer.dll)
    na pasta = “….\ProjetoModeloDDD.MVC\bin”
    Nao resolvel ele nao lista nao funciona como resolve isso estou travado nisso, obrigado.

  101. Aos desenvolvedores que instalarem a versão do Entity >= 6.x, adicionem a linha ao construtor do contexto na camada de Infra para evitar a exception de provider do ADO.NET:
    var ensureDLLIsCopied = SqlProviderServices.Instance;

    Após essa dica, Eduardo, parabéns pelo ótimo tutorial o/

  102. Parabéns Eduardo pelo material magnífico , muito bom mesmo , tanto que iniciei um projeto meu na mesma arquitetura do tutorial e está tudo funcionando perfeitamente , só estou com uma dificuldade em implementar uma view de Create para um Mestre e Detalhe , ou seja uma tela de proposta comercial , onde existe uma tabela principal e uma de detalhes onde serão incluidos os items. Nos materiais que tenho visto na Net acho muita coisa com ajax , gostaria de saber de você se pode me ajudar com um exemplo , apenas me dar o caminho das pedras para que eu consiga fazer. E mais uma vez parabéns pelo tutorial !!!!!!

    • Bom dia Eduardo, sigo bastante seus artigos e estou no desenvolvimento de um projeto Core com Angular utilizando tudo de boas práticas porém no decorrer do projeto estou vendo que não havia tanta necessidade utilizar o AutoMapper, quais os pontos positivos em utilizar o mapper em um projeto de grande porte levando em consideração que a empresa quer agilidade nas entregas tentando ao máximo não utilizar uma arquitetura meia boca como você mesmo menciona.

  103. Bom dia Eduardo, sigo bastante seus artigos e estou no desenvolvimento de um projeto Core com Angular utilizando tudo de boas práticas porém no decorrer do projeto estou vendo que não havia tanta necessidade utilizar o AutoMapper, quais os pontos positivos em utilizar o mapper em um projeto de grande porte levando em consideração que a empresa quer agilidade nas entregas tentando ao máximo não utilizar uma arquitetura meia boca como você mesmo menciona.

  104. Bom dia Eduardo

    Cara como ficaria meu RepositoryBase quando utilizado o EF Core, meu construtor hoje se encontra da seguinte forma:

    public ProgrammersContext(DbContextOptions options)
    :base(options)
    {

    }

    Porém no modelo apresentado, você apenas instancia o seu contexto no seu repository passando a QS, como ficar esse mesmo exemplo porém com .NET Core.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *