Desacoplando o ASP.NET Identity do MVC e Domínio

O ASP.NET Identity é uma ótima solução para a gestão dos usuários em sua aplicação, porém seu design é diretamente acoplado ao ASP.NET MVC e também devemos evitar de utilizar suas referências no domínio da aplicação.

Desacoplando o ASP.NET Identity. Finalmente após muitos pedidos eu consegui colocar a mão na massa e desenvolver um projeto modelo para ser usado como referência.

Desacoplando o ASP.NET Identity do MVC e Domínio

Como sabemos o ASP.NET Identity depende diretamente do EF (ou outros), Owin e System.Web, logo todas as implementações do ASP.NET Identity ficam de alguma forma acopladas em nossa camada de apresentação. Quando possuímos uma aplicação onde o usuário é uma peça importante no negócio existe a necessidade de representá-lo na camada de domínio, porém é altamente recomendado que a camada de domínio não conheça tecnologias terceiras (Identity, EF, outros).

Como resolver esse problema?

Foi após alguns estudos que cheguei no modelo que considero ser a “melhor abstração possível”, pois para o ASP.NET Identity funcionar na camada de apresentação é obrigatório levar algumas dependências, porém desde que esteja isolado em outra camada já conseguiremos ótimas boas vantagens.

Aviso: Caso você não conheça o ASP.NET Identity, DDD e Injeção de dependência sugiro que comece pelos tutoriais:

Neste tutorial você encontrará as seguintes tecnologias utilizadas

  • ASP.NET MVC 5
  • ASP.NET Identity 2
  • Entity Framework 6
  • Fluent API
  • Injeção de Dependência com Simple Injector
  • Owin
  • RestSharp para implementação do Twilio API (SMS)

Existem dois grandes objetivos nesta proposta, o primeiro objetivo é a reutilização, pois com um uma única solução (camada) de gestão de usuários é possível atender N aplicações, facilitando o gerenciamento e manutenção.

O segundo objetivo é permitir que a camada de domínio represente o usuário de forma abstraída, logo não existe referência direta do IdentityUser no domínio, porém é possível consultar os dados de usuário e incluir / modificar as informações salvas.

O primeiro passo é abstrair tudo, mover as dependências do Identity para uma camada isolada, depois injetar no MVC os objetos necessários, para essa implementação eu utilizei o Simple Injector, que como o próprio nome diz, é bem simples, rápido e atendeu bem a necessidade.

Com o Identity isolado e injetado devidamente na camada de apresentação (MVC) basta criar uma camada de acesso a dados que irá fornecer meios do domínio consumir dados do usuário de forma abstraída. A grande sacada está no uso correto do Fluent API e claro muita injeção de dependência.

A solução desde modelo não visa atender completamente a filosofia do DDD, pois procurei simplificar o bastante para deixar simples de modificar, por exemplo adicionando uma camada de Application. Portanto quem utilizar esta arquitetura deve estar ciente que algumas coisas a mais ainda precisam ser feitas.

Gostaria de ressaltar também que o template de projeto ASP.NET MVC que o Visual Studio fornece possui vários problemas de design de código. As controllers de Account e Manage do usuário precisaram ser parcialmente re-escritas para atender a injeção do Identity, problemas como mais de um construtor público e utilização do pattern (ou anti pattern?) Service Locator foram encontrados e retirados.

Para quem quiser acompanhar em detalhes técnicos toda a implementação dessa solução eu preparei o vídeo a seguir.

* Assine meu canal no Youtube 🙂

O código fonte desta solução está disponível no GitHub, caso queira propor alguma melhoria faça um Pull Request, será muito bem recebido.


Se você estiver interessado em conhecer mais e aprender como desenvolver aplicações Web com arquitetura baseada em DDD, aplicando os princípios SOLID, diversos Design Patterns e escrevendo testes de unidade inscreva-se em meu curso:

Vamos continuar a troca de experiências, deixe seu comentário abaixo, se gostou e concorda com o artigo compartilhe com seus colegas para transmitirmos o conhecimento para o máximo de pessoas possíveis. ;)

Vamos precisar reescrever essa aplicação do zero.

Quem nunca disse ou ouviu isso? Vamos entender os motivos por trás dessa icônica frase.

Vamos precisar reescrever essa aplicação do zero! É a frase de rendição, é sinal que as coisas foram para o caminho errado. Dias, meses, anos de desenvolvimento que serão jogados fora por falta de um bom planejamento.

Vamos precisar reescrever essa aplicação do zero.

Quando chegamos nessa situação geralmente estamos diante de alguns dos cenários a seguir:

  • A tecnologia da aplicação é antiga demais e os novos recursos demandam mais tecnologia.
  • A arquitetura da aplicação é uma engenhoca complexa e sem sentido.
  • Devido a diversas implementações e manutenções do passado feitas de forma irresponsável ou sem padrão a aplicação se tornou a famosa “colcha de retalhos”, qualquer tipo de mudança é sofrível e demorada.
  • A cada mudança surgem diversos bugs em todas as partes da aplicação, pois existe muito acoplamento entre suas divisões, “tudo está acoplado com tudo”.
  • O time que trabalha na aplicação atualmente não concorda com a forma com que foi escrita e não está satisfeito em trabalhar nela.

Algumas situações muitas vezes não possuem uma escapatória, por exemplo o envelhecimento natural da aplicação. É muito caro manter uma aplicação sempre alinhada com a última versão da tecnologia, logo, algumas vezes prefere-se optar por saltos (atualizar a cada X tempo) ou simplesmente reescreve-la depois de alguns anos.

O cenário de envelhecimento da aplicação é um dos menores, geralmente a aplicação morre muito antes da hora. Eu trabalhei em uma empresa onde assisti a mesma aplicação ser reescrita 1 vez ao ano durante 3 anos. O que ocorre de tão errado assim?

Existem muitos motivos para tudo dar errado:

  • Equipe tecnicamente despreparada.
  • Falta de um líder técnico ou arquiteto que conduza o time e evite a deformação da aplicação.
  • Escopo mal planejado, falta de entendimento da entrega.
  • Prazo mal calculado.
  • Falta de visão. Típico caso do sisteminha de cadastro que virou um “ERP”.
  • Gestor de equipe que pula etapas e/ou não valoriza (não conhece) boas práticas, impondo uma metodologia que funciona apenas na teoria dele.

Motivos para dar errado são muitos, fazer software da forma correta é infinitamente mais complexo que simplesmente entregar software. É necessário ter uma boa equipe, um bom líder e um bom gestor.

Software é um bem durável assim como uma TV, Geladeira ou Carro, paga-se muito caro para desenvolve-lo e muito caro para mante-lo. A diferença é que o software precisa ser flexível e adaptar-se às constantes mudanças de escopo, logo não pode possuir uma engenharia fechada como uma TV e geralmente é ai onde mora a maioria dos problemas.

Para garantir um bom funcionamento da aplicação de forma que ela se adapte às diversas mudanças de escopo com o mínimo de esforço necessário e sem gerar outros problemas secundários, é preciso projetar a aplicação, não basta simplesmente escrever a aplicação e entregar.

Alguns pontos importantes devem sempre ser abordados:

Processo

Processo de desenvolvimento de software é um tema extenso demais, portanto deixarei apenas alguns pontos em destaque que devem ser levados bastante em consideração.

Processo de desenvolvimento de software é um processo diferente de outros, porém infelizmente ainda existem gestores que imaginam que desenvolver uma aplicação é o mesmo que construir um prédio, um navio ou um avião.

Durante a construção de um prédio com a obra em estágio avançado é praticamente impossível aplicar mudanças que mudam o aspecto do projeto, existe uma engenharia fechada e projetada para ser daquela forma, qualquer mudança poderia impactar em ter que iniciar novamente do zero.

Uma aplicação bem projetada deve ser flexível e estar aberta para mudanças de escopo com menor esforço necessário, portanto não devemos nos apegar em simplesmente entregar o que foi inicialmente levantado.

Uma das formas mais práticas de atender a necessidade do cliente é a entrega contínua, releases parciais para acompanhamento e feedback do cliente, é muito mais fácil ajustar uma mudança de escopo com a aplicação 30% desenvolvida do que se estivesse 100%.

Focar em definir bem os requisitos das entregas mais próximas é muito melhor que tentar documentar 100% do projeto antes mesmo de iniciar a codificação.

Sim estamos falando de metodologias ágeis como o Scrum por exemplo, um projeto de software é diferente de um projeto de construção civil e merece um framework de desenvolvimento interativo e incremental.

Planejamento

É necessário analisar qual será o porte da aplicação, não existe uma receita para todo tipo de aplicação, se ela for grande e complexa é necessário abordar alguma prática de arquitetura, por exemplo DDD.

Se a aplicação for simples é necessário evitar exageros e complexidades que não beneficiam as funcionalidades da aplicação.

Orientações como o KISS e o YAGNI dizem para evitar os exageros e manter a aplicação simples, é fato, mas isso não significa que você deve fazer tudo na camada de apresentação por exemplo, uma mínima divisão de responsabilidades é essencial para a qualidade de qualquer tipo de aplicação.

Arquitetura

Arquitetura é a base de tudo, é muito importante fazer a escolha ideal e evitar a famosa “arquitetura BOLOVO” de 3 camadas (Modelo, Business e DataAccess).
Hoje em dia está claro que apesar de funcionar e ser simples esse modelo traz muitos problemas.

É muito importante ter uma pessoa no papel de arquiteto, que conheça diversas estratégias de arquitetura e saiba aplicar bem os inúmeros patterns disponíveis.

Uma vez que possui sua arquitetura definida a aplicação deve se manter dentro do aspecto da arquitetura original, corromper camadas para acessar mais facilmente o banco ou para resolver mais rapidamente um problema pode ser considerado um crime.

Descaracterizar a arquitetura de uma aplicação é o primeiro passo para a famosa “Colcha de Retalhos”. O arquiteto ou líder técnico deve ser responsável por garantir que a arquitetura não esteja sendo corrompida e que seja mantida dentro de sua proposta em toda extensão da aplicação.

Codificação

Mesmo com uma arquitetura definida a tarefa de codificação ainda é complexa e não existem motivos para ser diferente. Codificar exige muitas habilidades além do próprio conhecimento da linguagem e plataforma.

É importantíssimo valorizar os princípios básicos da orientação à objetos como o SOLID que apesar de ser básico podemos dizer que grande parte dos desenvolvedores ainda não sabem como escrever código usando injeção de dependência (DIP) para evitar o alto acoplamento. Realizam heranças sem sentido apenas pelo fato de um objeto herdar hierarquicamente de outro no mundo real. Deixam o princípio de responsabilidade única de lado (SRP) e não criam classes extensíveis (OCP) deixando o código sempre aberto.

Entre outros pontos falhos não citados, os mencionados acima já são responsáveis por grande parte dos problemas existentes em nossas aplicações. Codificar não é uma tarefa menos grandiosa como arquitetar um sistema, pelo contrário, precisamos valorizar mais o programador que possui esses conhecimentos.

Padrões de codificação como nomenclaturas e regras são importantes para manter a expressividade e facilidade de leitura do código. Antigamente programadores se gabavam por fazer códigos que somente eles entendiam, isso não deve existir, o código é uma série de instruções que devem ser de leitura clara e leve, muitas vezes dispensando uma documentação própria.

Uma técnica de codificação que vem ganhando popularidade é o TDD, apesar do TDD ter seu nome diretamente relacionado com testes o TDD na verdade é sobre codificação, os testes que guiam a codificação via TDD servem para garantir a qualidade do código que no final também garantem a sua testabilidade.

Testes

Testes é um assunto complexo, primeiramente devemos entender que teste de software não é apenas rodar a aplicação e ver se tudo está funcionando.

Existe mais de um tipo de teste, podendo ser de unidade, de integração e etc.

Os testes de unidade são necessários quase sempre, podemos dizer que 80% de cobertura de código através dos testes é um resultado bem positivo. Testes de unidade são muito importantes para garantir a boa escrita do código e validar a sua funcionalidade durante o desenvolvimento. Se durante a codificação um teste falhar pode significar que alguma coisa foi feita de forma que o código deixou de funcionar como deveria, logo evitará o deploy prematuro em produção e que o cliente tenha a infelicidade de descobrir um novo bug.

Descobrir um bug em tempo de codificação é N vezes mais barato que descobrir um bug em produção, evita retrabalho, horas extras, replanejamento de deploy, insatisfação com o cliente etc.

Muitas pessoas alegam que escrever testes de unidade fazem o software custar mais caro, pois aumenta mais o esforço de codificação. Isto parece fazer sentido se olharmos apenas no sentido da entrega, mas mesmo assim não faz. Os testes exigem mais esforço de codificação, porém conforme a cobertura de testes aumenta a velocidade de entrega aumenta junto, pois os testes facilitam muito as futuras modificações.

Contabilizar o esforço apenas baseado na entrega é uma falha. Devemos sempre levar em conta a manutenção e evolução, e quando falhamos nesse aspecto estamos iniciando o ponto onde a aplicação vai se tornar cada vez mais complexa para se testar, evoluir, receber manutenções.

Costumo dizer que programamos uma aplicação durante 6 meses e a mantemos durante 3 anos ou mais, sendo assim nosso foco deveria ser na manutenção e evolução e não apenas na entrega. Todo lucro obtido numa entrega mal planejada será perdido durante a manutenção, podendo inclusive chegar ao negativo, e esse é um dos principais motivos que levam diversos projetos falharem e se transformarem em prejuízo quando deveriam continuar gerando lucros.

Os testes de unidade são de responsabilidade do desenvolvedor, os testes de integração e etc podem ser de responsabilidade de um profissional de qualidade ou simplesmente de toda a equipe (equipes multidisciplinares sabem codificar e testar).

Testes de unidade garantem a qualidade de escrita do código e de sua funcionalidade, um código que não está coberto por testes não é um código confiável. Não existe processo ágil de desenvolvimento sem testes, portanto está claro. Testar é preciso!

Quando tudo deu errado.

O planejamento da aplicação não foi bem feito, a arquitetura não foi bem desenhada para atender o propósito da aplicação, a codificação está estruturada, acoplada e sem padrão, não existem testes de unidade e realizar qualquer manutenção significa alterar diversas partes do código e ser obrigado a testar manualmente todas funcionalidades de ponta a ponta, mesmo assim sempre escapando alguns novos bugs.

As noites são longas quando é necessária alguma manutenção, o deploy em produção é uma aventura preocupante, a satisfação de trabalhar no projeto já não existe mais e a pressão não vale a pena.

O gestor do projeto não aceita mais tantos bugs e exige mais assertividade, questionando inclusive a capacidade técnica da equipe, o cliente não aceita mais os prazos para ajustes simples e não quer pagar a mais por isso também.

Não dá mais!  Vamos precisar reescrever essa aplicação do zero.


Se você estiver interessado em conhecer mais e aprender como desenvolver aplicações Web com arquitetura baseada em DDD, aplicando os princípios SOLID, diversos Design Patterns e escrevendo testes de unidade inscreva-se em meu curso:

Vamos continuar a troca de experiências, deixe seu comentário abaixo, se gostou e concorda com o artigo compartilhe com seus colegas para transmitirmos essa mensagem para o máximo de pessoas possíveis. 😉

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 😉

ASP.Net MVC – AutoMapper e View Models

O AutoMapper é uma biblioteca pequena e simples construída para resolver um problema aparentemente complexo, que é livrar-se de um código que mapeou um objeto para outro. Este tipo de problema é muito comum e relativamente trabalhoso de resolver,  a ferramenta AutoMapper atua nesse cenário de forma simples e elegante.

ASP.Net MVC AutoMapper

No artigo anterior foi abordado o padrão View Model no ASP.Net MVC, esse padrão ajuda a organizar o código, pois divide as responsabilidades entre as Models de domínio e as Models que atendem Views, evitando que as Models de domínio sejam alteradas e poluídas com dados desnecessários ao domínio.

A primeira técnica de trabalhar com View Models foi abordada no artigo anterior.
A técnica abordada neste artigo é mais complexa e necessita de um mapeamento entre objetos que é feito com a ajuda da ferramenta AutoMapper.

No livro Padrões de Arquitetura de Aplicações Corporativas, Martin Fowler descreve um padrão base chamado Mapper. O AutoMapper foi desenvolvido por Jimmy Bogard, um dos autores do livro ASP.Net MVC 4 in Action.

Mapeando uma Model de domínio para uma View Model

O cenário deste exemplo é baseado em um sistema muito simples que consulta os dados de um cliente cadastrado e informa um número da sorte gerado randomicamente para este cliente.

Neste cenário possuímos a Model de domínio (cliente).

using System;

namespace MvcMapping.Models
{
    public class Cliente
    {
        public string Nome { get; set; }
        public string Sobrenome { get; set; }
        public DateTime DataNascimento { get; set; }
        public bool Ativo { get; set; }
    }
}

Note que não existe referência ao dado de número da sorte, pois ele é exibido apenas na View e não é armazenado com os dados de cliente, logo torna-se desnecessário fazer parte da modelagem da Model.

Na técnica apresentada anteriormente a solução seria criar uma View Model com uma propriedade do tipo cliente e complementar com dados adicionais a serem exibidos na View.
Este artigo irá abordar outra técnica que consiste em criar uma classe com a mesma estrutura de cliente e mais os novos dados adicionais, chamaremos ela de ClienteViewModel e estará disponível em uma pasta raiz do projeto MVC chamada ViewModels.

using System;
using System.ComponentModel.DataAnnotations;

namespace MvcMapping.ViewModels
{
    public class ClienteViewModel
    {

        [Required(ErrorMessage = "Preencher campo Nome")]
        public string Nome { get; set; }

        public string Sobrenome { get; set; }

        [Required(ErrorMessage = "Preencher campo Data de Nascimento")]
        [Display(Name = "Data de Nascimento")]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
        [DataType(DataType.Date, ErrorMessage="Data em formato inválido")]
        public DateTime DataNascimento { get; set; }

        public bool Ativo { get; set; }

        public int NumeroDaSorte { get; set; }
    }
}

Na classe ClienteViewModel possuímos a mesma estrutura de clientes, mais o dado adicional de número da sorte e os DataAnnotations para validação de formulário.

Até este momento já é possível listar três benefícios imediatos:

  • A Model de domínio não precisou ser modificada sem necessidade.
  • A Model de domínio não está poluída com DataAnnotations de validação de formulário.
  • A manutenção destas classes torna-se muito mais fácil, uma vez que a Model de domínio não está amarrada às características de uma View.

Após a separação das responsabilidades temos uma Model e uma View Model, ambas representando a entidade cliente, agora é necessário mapear um objeto ao outro para que a ClienteController receba a Model cliente e responda para View uma ClienteViewModel (e vice-versa), esse trabalho é executado pelo AutoMapper.

Configurando o AutoMapper no projeto ASP.Net MVC

Primeiramente é necessário configurar as referências das bibliotecas do AutoMapper e isto pode ser feito facilmente com o NuGet

PM> Install-Package AutoMapper

No projeto MVC crie uma pasta vazia chamada Mappers, dentro desta pasta será necessário criar uma classe que servirá de configuração dos profiles de mapeamento (Model > View Model) e (View Model > Model), esses profiles de mapeamento foram separados em dois arquivos, confira como abaixo como criar cada um deles.

Classe AutoMapperConfig

using AutoMapper;

namespace MvcMapping.Mappers
{
    public class AutoMapperConfig
    {
        public static void RegisterMappings()
        {
            Mapper.Initialize(x =>
            {
                x.AddProfile<DomainToViewModelMappingProfile>();
                x.AddProfile<ViewModelToDomainMappingProfile>();
            });
        }
    }
}

Classe DomainToViewModelMappingProfile

[UPDATE – 12/2015]Não é mais possível fazer o override do ProfileName nas novas versões do AutoMapper. Basta não sobrescrever esta property

using AutoMapper;
using MvcMapping.Models;
using MvcMapping.ViewModels;

namespace MvcMapping.Mappers
{
    public class DomainToViewModelMappingProfile : Profile
    {
        // Não realizar este override na versão 4.x e superiores
        public override string ProfileName
        {
            get { return "DomainToViewModelMappings"; }
        }

        protected override void Configure()
        {
            Mapper.CreateMap<Cliente, ClienteViewModel>();
        }
    }
}

Classe ViewModelToDomainMappingProfile

using AutoMapper;
using MvcMapping.Models;
using MvcMapping.ViewModels;

namespace MvcMapping.Mappers
{
    public class ViewModelToDomainMappingProfile : Profile
    {
        // Não realizar este override na versão 4.x e superiores
        public override string ProfileName
        {
            get { return "ViewModelToDomainMappings"; }
        }

        protected override void Configure()
        {
            Mapper.CreateMap<ClienteViewModel, Cliente>();
        }
    }
}

Esta é a estrutura necessária para configurar o AutoMapper de forma a utilizar o mínimo possível de código de mapeamento em outras classes da aplicação.

  • AutoMapperConfig > Inicializa os profiles de mapeamento (Model > View Model) e (ViewModel > Model).
  • DomainToViewModelMappingProfile > Profile de mapeamento (Model > View Model)
  • ViewModelToDomainMappingProfile > Profile de mapeamento (View Model > Model)

Confira como o projeto ficou estruturado

Projeto ASP.Net MVC AutoMapper

Neste momento resta apenas configurar que a classe AutoMapperConfig seja inicializada junto com a aplicação para registrar os profiles de mapeamento, essa configuração é feita no arquivo Global.asax

using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using MvcMapping.Mappers;

namespace MvcMapping
{

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();

            // Configurando o AutoMapper para registrar os profiles
            // de mapeamento durante a inicialização da aplicação.
            AutoMapperConfig.RegisterMappings();
        }
    }
}

O AutoMapper está devidamente configurado na aplicação, no próximo passo será feita a conversão da Model cliente para a ClienteViewModel na Controller através do mapeamento que foi criado, confira como ficou o código da ClienteController

using System;
using System.Web.Mvc;
using MvcMapping.Models;
using MvcMapping.ViewModels;
using AutoMapper;

namespace MvcMapping.Controllers
{
    public class ClienteController : Controller
    {
        public ActionResult Index()
        {
            var rdnGen = new Random();

            // Um fake de uma consulta de cliente na base de dados.
            var cliente = new Cliente {
                                            Nome = "Eduardo",
                                            Sobrenome = "Pires",
                                            DataNascimento = Convert.ToDateTime("24/04/1982"),
                                            Ativo = true,
                                      };

            // Transformando a Model Cliente em ClienteViewModel
            var clienteView = Mapper.Map<Cliente, ClienteViewModel>(cliente);

            // Atribuindo valor aos dados adicionais da entidade Cliente
            clienteView.NumeroDaSorte = rdnGen.Next(1, 100);

            return View(clienteView);
        }
    }
}

Note que foi necessário apenas uma linha para transformar a Model Cliente em ClienteViewModel. De forma muito elegante foi criado um objeto do tipo ClienteViewModel já populado com os dados existentes no objeto Cliente.

A partir deste momento o AutoMapper está fazendo o trabalho de mapeamento e a View está recebendo uma View Model compatível com suas necessidades, confira o código da View

@model MvcMapping.ViewModels.ClienteViewModel

@{
    ViewBag.Title = "Sorte do Dia";
}

<hgroup class="title">
    <h1>@ViewBag.Title.</h1>
</hgroup>

<table>
    <tr>
        <td>
            @Html.LabelFor(m => m.Nome)
            @Html.DisplayFor(m => m.Nome)
        </td>
    </tr>
    <tr>
        <td>
            @Html.LabelFor(m => m.Sobrenome)
            @Html.DisplayFor(m => m.Sobrenome)
        </td>
    </tr>
    <tr>
        <td>
            @Html.LabelFor(m => m.DataNascimento)
            @Html.DisplayFor(m => m.DataNascimento)
        </td>
    </tr>
    <tr>
        <td>
            @Html.LabelFor(m => m.Ativo)
            @Html.DisplayFor(m => m.Ativo)
        </td>
    </tr>
    <tr>
        <td>
            @Html.LabelFor(m => m.NumeroDaSorte)
            @Html.DisplayFor(m => m.NumeroDaSorte)
        </td>
    </tr>
</table>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Para mapear mais Models / View Models basta editar os arquivos DomainToViewModelMappingProfile e ViewModelToDomainMappingProfile com os mapeamentos necessários.

Achou muito trabalhoso ter que montar a estrutura de pasta e os 3 arquivos de mapeamento? Existe uma forma que dispensa toda essa configuração (inclusive inicialização no Global.asax), basta adicionar uma linha a mais em cada momento que houver o mapeamento, confira.

public class ClienteController : Controller
{
    public ActionResult Index()
    {
        var rdnGen = new Random();

        // Um fake de uma consulta de cliente na base de dados.
        var cliente = new Cliente {
                                        Nome = "Eduardo",
                                        Sobrenome = "Pires",
                                        DataNascimento = Convert.ToDateTime("24/04/1982"),
                                        Ativo = true,
                                    };

        // Criando o Mapeamento por demanda.
        Mapper.CreateMap<Cliente, ClienteViewModel>();

        // Transformando a Model Cliente em ClienteViewModel
        var clienteView = Mapper.Map<Cliente, ClienteViewModel>(cliente);

        // Atribuindo valor aos dados adicionais da entidade Cliente
        clienteView.NumeroDaSorte = rdnGen.Next(1, 100);

        return View(clienteView);
    }
}

Apesar de ser mais simples eu pessoalmente não recomendo utilizar o mapeamento desta forma, pois além de somar uma linha a mais em todo momento de executar o mapeamento, o comando de criação de mapeamento não fica centralizado, é difícil ter visão dos mapeamentos já existentes e dificulta também a manutenção.

Resumo

Utilizar o AutoMapper é muito simples conforme foi exemplificado, colabora para adoção do padrão View Model e evita a necessidade de escrever extensos códigos de mapeamento, assim proporcionando mais agilidade no desenvolvimento e facilitando a manutenção, e claro, o código final fica com um aspecto muito mais elegante.

Existem outras ferramentas para mapeamento com a mesma finalidade, a mais popular até o momento é o AutoMapper.

Referências

Nota

“Como mencionado no artigo anterior o padrão View Model está presente no MVC, MVP e MVVM, este artigo aborda a utilização deste padrão para MVC.”

Espero que este artigo ajude a entender o conceito do padrão View Model e o mapeamento de objetos através do AutoMapper.

Feedbacks são sempre muito bem vindos, utilize os comentários abaixo.

ASP.Net MVC – View Model Pattern – Quando e como utilizar?

No desenvolvimento em ASP.Net utilizando o framework MVC é muito comum o uso do pattern View Model, esse pattern proporciona uma melhor organização do código e gestão dos dados utilizados na View, confira em quais situações ele é utilizável e algumas maneiras de como aplicá-lo.

A necessidade da utilização do pattern View Model surge na maioria dos projetos ASP.Net MVC, para os iniciantes costuma causar alguma confusão, porém é muito útil e poupa um bom trabalho.

O conceito de View Model não limita-se apenas para o ASP.Net MVC, você poderá encontrar referências sobre View Model para padrões MVC, MVP e MVVM, que por sua vez é implementado em tecnologias como ASP.Net, Silverlight e WPF.

Este artigo é dedicado para o entendimento do padrão View Model utilizando ASP.Net MVC.

O que é um ASP.Net MVC View Model?

No ASP.Net MVC os View Models nos permitem modelar várias entidades a partir de um ou mais modelos em um único objeto, eu gosto de usar como exemplo a comparação de View Models com uma DTO, pois ambas são soluções que foram projetadas para centralizar um conjunto de dados de diversas fontes assim evitando a necessidade de realizar várias chamadas para se obter todos os dados necessários e evitar a necessidade de alterar um modelo de domínio para realizar o transporte de algum dado específico.

Resumindo, um View Model representa um conjunto de uma ou mais Models e outros dados que serão representados em uma View que necessita exibir determinado conjunto de informações. A imagem abaixo ilustra o conceito de um View Model:

ASP.Net  MVC View Model Pattern

Utilizando uma View Model dedicada contendo a Model de domínio

Imagine que estamos desenvolvendo uma aplicação web de uma loja virtual onde possuímos a classe Produto:

public class Produto
{
    public string Nome { get; set; }
    public decimal Valor { get; set; }
}

Porém na View de carrinho de compras além das informações contidas na classe Produto é necessário exibir uma mensagem e o valor total do carrinho para vários produtos. O que fazer? Modificar a classe Produtos para conter essas informações?

Modificar a classe Produto não seria uma boa alternativa, afinal esses dados adicionais não fazem sentido pertencerem a entidade Produto, são dados pertinentes a View de carrinho de compras.

É nesse momento que o pattern View Model entra em ação para resolver esse problema de design. Criaremos então uma classe que irá prover dados para esta View e essa classe será uma View Model de carrinho de compras.

public class CarrinhoComprasViewModel
{
	public IEnumerable Produtos { get; set; }
	public decimal TotalCarrinho { get; set; }
	public string Mensagem { get; set; }
}

Podemos observar que esta View Model possui um IEnumerable de Produtos para uma lista de produtos e mais os dados de valor e mensagem que irão ser exibidos na View.
Não é um tipo de classe especial, é uma classe como qualquer outra Model, porém escrita especificamente para atender a uma View.

Confira o código da Controller de carrinho de compras.

public class CarrinhoComprasController : Controller
{
    public ActionResult Index()
    {

        // Criando uma lista de produtos fake para exibição na View
        var produtos = new List<Produto>();
        for (int i = 0; i < 10; i++)
	    {
            produtos.Add(new Produto
                            { Nome = "Produto " + i, Valor = 1.13M * i }
                        );
        }

        // Populando a model para exibição na View
        var model = new CarrinhoComprasViewModel
	    {
            Produtos = produtos,
            TotalCarrinho = produtos.Sum(p => p.Valor),
            Mensagem = "Obrigado por comprar conosco!"
        };

        return View(model);
    }

}

E por fim a View de carrinho de compras

@model MeuExemploMVC.Models.CarrinhoComprasViewModel

@{
    ViewBag.Title = "Carrinho de Compras";
}

<h2>@Model.Mensagem
</h2>
<fieldset>
    <legend>Carrinho de Compras</legend>

    <table>
        <caption>Produtos no Carrinho</caption>
        <thead>
        <tr>
            <th>Produto</th>
            <th>Valor</th>
        </tr>
        </thead>
        <tbody>
        @foreach (var produto in Model.Produtos) {
            <tr>
                <td>@produto.Nome</td>
                <td>@produto.Valor</td>
            </tr>
        }
        </tbody>
        <tfoot>
            <tr>
                <td><strong>Total</strong></td>
                <td>@Model.TotalCarrinho</td>
            </tr>
        </tfoot>
    </table>

</fieldset>

O pattern de View Model está aplicado e não será mais necessário modificar a Model de Produto para adequar a View.

O arquivo físico de uma View Model pode estar em diferentes lugares, sendo:

  • Em uma pasta chamada ViewModels na estrutura raiz do projeto MVC (aplicações pequenas)
  • Uma *.dll referenciada no projeto MVC (aplicações de qualquer tamanho)
  • Em projetos separados (como uma camada de serviços) para gerar dados específicos (aplicações grandes)

Utilizando AutoMapper para realizar o mapeamento de uma Model e suas variantes

Uma outra forma de utilizar View Models seria criando um mapeamento entre a Model entidade de domínio e a View Model que será exibida na View.

Os autores do livro ASP.Net MVC 4 in Action defendem fortemente a utilização de mapeamento entre as Models e suas possíveis variantes.

Com base no exemplo acima, a classe Produto poderia ter uma variante chamada ProdutoViewModel, qual possuiria os mesmos atributos de Produto entre outros mais.

O mapeamento entre essas duas Models seria feito através da ferramenta AutoMapper.
Este é um processo mais complexo e será abordado em meu post exclusivo sobre utilização do AutoMapper.

Benefícios de usar uma View Model

  • Não precisar alterar uma classe Model para atender as necessidades de uma View.
  • Poder agrupar informações de uma ou mais Models em uma única classe, poupando a necessidade de realizar N consultas.
  • Um dado não contido em uma Model de domínio pode ser facilmente transportado através de uma View Model.
  • Mudanças são muito mais fáceis de se realizar e sem afetar a Model do domínio.
  • Não é necessário “poluir” as Models de domínio com DataAnnotations de validação de formulário, pois estas podem estar contidas diretamente na View Model.

Resumo

O uso de View Models é muito recomendado e irá ajudar a organizar e gerenciar os dados a serem transportados e exibidos, proporcionando flexibilidade para montar conjuntos de dados compatíveis com as necessidades da View.

No MVC existe o conceito de separação de responsabilidades onde “M” (Model) é considerada a menos importante, pois nem sempre a Model estará presente no projeto MVC e sim numa camada de domínio que irá prover estas classes. A Model do MVC está voltada ao uso na View, portanto algumas técnicas são necessárias para separar e mapear Models de entidades de domínio para Models do projeto MVC.

Referências

Aguardem o próximo artigo complementar sobre AutoMapper 😉
Dúvidas e feedbacks são sempre muito bem vindos, utilize os comentários abaixo.

O que é POCO?

Olá pessoal, O que é POCO? O que seria uma classe POCO?

Hoje em dia utilizar um ORM como Entity Framework ou NHibernate é bem comum, aplicar conceitos do DDD também vem sido bem abordados e discutidos e em todas essas abordagens acaba surgindo o uso de POCO. Afinal o que é POCO?

Tentar decifrar esse nome vai ser bem difícil, POCO significa Plain OLD CLR Object, tentando traduzir isso eu gosto de chamar POCO de “Bom e velho objeto do CLR”.
POCO é um acrônimo de POJO Plain OLD Java Object, criado por Martin Fowler (um expert em OOP) como ele vem de Java acabou dando esse nome, então os especialistas em .Net fizeram uma pequena mudança para trazer esse conceito ao nosso mundo e surgiu o POCO (mas é o mesmo conceito, não muda nada).

Legal, mas ainda não entendi o que é POCO?

É fácil de entender, POCO é uma classe que segue o ideal do OOP, pois tem estado e comportamento, porém não depende e não conhece nenhum recurso externo além do Framework .Net.

Uma classe POCO é utilizada como classe de domínio (negócio) da sua aplicação, o que chamo de Modelo de Domínio. Um Modelo de Domínio é formado pelas classes que compõem a estrutura de negócio do mundo real.

Nós não desenvolvemos sistemas apenas baseados no Framework .Net, quase sempre necessitamos de uma ferramenta externa, por exemplo um ORM, que por sua vez impõe o uso de referências como classes, interfaces, decorações nos métodos etc…

Construir uma classe POCO é escrever uma classe que contenha atributos, construtores e métodos mas que não dependam de nada mais do que o próprio .Net Framework forneça.

Quem já utilizou o Entity Framework na forma Database First já viu como que fica a bagunça de uma classe? Acabamos gerando um único arquivo EDMX com muitas dependências, herdando de um objeto ObjectContext. Geralmente esse código é bastante poluído e dificíl de estender.

    [EdmEntityTypeAttribute(NamespaceName="SistemaOS.Model", Name="Pessoas")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class Pessoas : EntityObject
    {
        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int32 id_pessoa
        {
            get
            {
                return _id_pessoa;
            }
            set
            {
                if (_id_pessoa != value)
                {
                    Onid_pessoaChanging(value);
                    ReportPropertyChanging("id_pessoa");
                    _id_pessoa = StructuralObject.SetValidValue(value, "id_pessoa");
                    ReportPropertyChanged("id_pessoa");
                    Onid_pessoaChanged();
                }
            }
        }
    }

Ou seja, estamos amarrados ao Entity Framework se deixarmos ele criar nossas classes de entidades.

Um exemplo simples de classe POCO:

    public class Pessoa
    {
        public string Nome { get; set; }
        public string Sobrenome { get; set; }
        public int Cpf { get; set; }

        public string NomeCompleto()
        {
            return Nome + " " + Sobrenome;
        }
    }

Veja que neste exemplo não dependemos de nada, é apenas uma classe, tratando de DDD o nosso domínio não pode depender de tecnologia, afinal a minha camada de domínio pode ser adaptada a um outro sistema que não utilizará o Entity Framework e tudo bem! Afinal minha classe POCO não depende disso.

Acredito que a vantagem de usar POCO é exatamente essa, podemos modelar nossas classes de domínio e portá-las para onde quiser, sem a dependência de nenhuma ferramenta externa.

Por isso recomendo que utilizem ferramentas que dê suporte a POCO, e isso não é difícil, por exemplo Entity Framework, NHibernate, WCF permitem trabalhar com POCO.

No Entity Framework, por exemplo, podemos trabalhar da forma Code First, ou seja, escrevemos primeiro classes POCO e no final a modelagem da base de dados é criada conforme a modelagem do nosso domínio.

Então uma classe POCO é uma classe anêmica?
– Não! Uma classe anêmica pode até ser uma classe POCO, mas nada diz que uma classe POCO deve ser anêmica, afinal ela pode possuir atributos e métodos.
Uma classe anêmica não possui métodos, e por alguns é considerada um anti-pattern, pois fere o conceito de orientação a objeto, mas isso é assunto para um outro artigo. 🙂

Uma classe POCO é como se fosse uma DTO então?
– Não! Uma DTO “Data Transfer Object” é outra coisa, pense em DTO como uma “sacola de dados”, ou seja, em um objeto DTO podemos ter dados das classes Pessoa, Endereço, Empresa.
DTO é um outro pattern desenhado justamente para reduzir o número de chamadas e a quantidade de dados necessários para trafegar entre camadas de sistemas, por exemplo, entre uma aplicação web e um serviço.
Uma classe POCO é sua classe de domínio e um DTO é o objeto para transitar dados apenas, podem possuir dados de mais de uma entidade e não possuem métodos, portanto não é POCO.

Se minha classe herda de uma classe base então não tenho uma classe POCO?
– Depende, desde que a classe base não tenha nenhuma dependência com outras camadas da aplicação e ferramentas externas, ainda é uma classe POCO.

Referências:

Espero que tenham aproveitado, se você gostou compartilhe esse artigo, se tiver dúvidas ou quiser contribuir com algo faça um comentário.

Até a próxima!