No .Net Architects Day eu apresentei rapidamente um exemplo iniciante de um sistema de blog durante minha palestra de DDD. Eu havia criado algumas entidades, post e comentário, e tudo funcionava.

Aí resolvi criar outra entidade: usuário. Criei a entidade, criei o controlador as views, liguei tudo, e tudo continuava funcionando. Não criei repositórios específicos, nem mapeamento, nem nada a mais, só a entidade e as partes de interface gráfica. Estava usando NHibernate para resolver o "problema" da relação objeto e dados relacionais. De repente a tabela apareceu lá, os dados salvavam corretamente, o SQL gerado era otimizado e eu estava feliz.

Tudo funcionava. Tudo automático. Muitos me perguntaram como isso foi feito. A resposta é muito simples. Além do NHibernate usei também um pouco de NHibernate Fluente e sua possibilidade de trabalhar automapeamento baseado em convenções. Minha classe de configuração do NHibernate fazia mapeamento de três formas: a básica do NH (com XML), a fluente (do NH fluente), e a automática. O código da classe de autoconfiguração é muito curto, cerca de 60 linhas:

public class Autoconfiguracao
{
    private static ISessionFactory _factory;
    public static ISessionFactory Configurar(bool gerarBanco = true)
    {
        if (_factory != null)
            return _factory;

        var config = Fluently.Configure()
            .Database(
            FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2005
            .ConnectionString(c =>
              c.Is(@"Data Source=.\sqlexpress;Initial Catalog=DNAD09Blog;Integrated Security=True"))
              .ShowSql()
        );

        config.Mappings(m =>
        {
            m.HbmMappings.AddFromAssemblyOf<Autoconfiguracao>();

            m.FluentMappings
                .AddFromAssemblyOf<Autoconfiguracao>();

            m.AutoMappings.Add(
                AutoPersistenceModel.MapEntitiesFromAssemblyOf<Postagem>()
                .WithSetup(s => s.IsBaseType = (type => type == typeof(EntidadeComId)))
                .ConventionDiscovery.Setup(c =>
                {
                    c.Add(PrimaryKey.Name.Is(x => x.EntityType.Name + "_Id"));
                    c.Add(DefaultLazy.AlwaysFalse());
                    //c.Add(ForeignKey.Format((prop, tipo) => prop.Name + "_Id"));
                    c.Add(Table.Is(x => x.EntityType.Name));
                }
                )
                .Where(t =>
                    t.Namespace == "Dnad09.Blog.Dominio.Entidades"
                    && t.IsInterface == false
                    && t.IsAbstract == false
                )
            );
        }
        );

        if (gerarBanco)
        {
            config.ExposeConfiguration(cfg =>
            {
                var schemaExport = new SchemaExport(cfg);
                schemaExport.Create(false, true);
            });
        }
        _factory = config.BuildSessionFactory();
        return _factory;
    }
}

 

Na parte de configuração, que vai até "config.Mappings" (linhas 17 a 42) todas as chamadas são baseadas em Lambdas. Em seguida se o flag gerar bancos é configurado então o banco é criado, e a factory do NH é retornada. Nela estão todas as configurações do NH, e a criação de sessões do NH, que é o que realmente importa, é muito facilitada. Para trocar o banco de dados para Oracle, por exemplo, bastaria trocar a chamada "Fluently.Configure" (linhas 9 a 15) para trabalhar com este banco de dados.

O mais interessante é a possibilidade de mapear automaticamente apenas a parte que interessa. Podemos mapear algumas classes automaticamente, aceitando as convenções, e em outras utilizar mapeamento fluente ou baseado em XML. Em um cliente recentemente fizemos isso através de atributos: se uma classe tinha um atributo de automapeamento que criamos, então usávamos ela no automapeamento. Senão, teríamos que trabalhar o mapeamento de forma fluente ou com XML.

A produtividade neste tipo de cenário é gigantesca. O foco é o domínio, ou seja, o coração de um software de negócios. A persistência dos dados não é sequer uma preocupação.

Essa abordagem toda é muito legal, mas levantou questões interessantes no .Net Architects Day, que foram inclusive discutidas em outras palestras, como a dada pelo Juliano, que foi mais focada em ORM. Entre elas, a mais polêmica foi sem dúvida a seguinte:

- O DBA morreu?

Minha resposta desta pergunta nesta quarta-feira de manhã. Aguardem.


Postado na(s) categoria(s) Mapeadores O/R pelo giovanni bassi em 6 de julho de 2009 às 07:43 | Tags: ,

Comentários


julho 6. 2009 10:25
Rafael Noronha
Ótima dica o Fluent NHibernate.

Hoje eu também escrevi sobre ORM (eterna campanha contra Datasets).

A discussão sobre o papel do DBA é interessante.
Acredito que eles são bem aproveitados em cenários complexos de manipulação de dados, independente do uso de ORM.

http://rafanoronha.net/http://rafanoronha.net/


Brazil Fernando Botelho
julho 6. 2009 11:14
Fernando Botelho
Levando-se em consideração que na maioria das empresas grandes tem-se o conceito de que os dados são da corporação, e não de um ou outro sistema, minha resposta à questão levantada é: não, claro que não.

Na minha concepção, assim como programadores não são pagos para somente escrevem códigos (ou não?), DBA's não somente escrevem procedimentos compilados no banco.

Fazer com que a estrutura de armazenamento seja criado pelo próprio framework de manipulação de dados me causa espécie por dois motivos: 1) estrutura pensada somente para uso por um sistema, e; 2) aplicação com permissão, inclusive, de manipular estrutura física em um banco de dados.

no site


Brazil Leandro
julho 6. 2009 12:15
Leandro
Fernando, não vejo muito problema nesses 2 motivos que lhe causam espécie.

1) Nesse ponto, existem duas abordagens, estamos falando de sistemas que utilizam uma mesma tecnologia ou tecnologias diferentes? Se for o caso da utilização de uma mesma tecnologia seria possível pensar no domínio da corporação inteira, sendo assim todos os sistemas(ou pq não um sistema com vários módulos que se integram?) utilizariam a mesma camada de domínio. Agora, se estivermos falando de tecnologias distintas em cada sistema, aí realmente seria um problema, talvez a utilização de serviços (SOA) fosse uma alternativa também.

2) A aplicação não precisa ter permissão permanente para manipular a estrutura do banco de dados, somente quando necessário, ou seja, é possível rodar a aplicação utilizando um usuário sem muitos privilégios quando estiver em produção.

no site


Brazil Fernando Botelho
julho 6. 2009 12:42
Fernando Botelho
Olá, Leandro.

Me baseei em empresas que possuem dados em "mainframes" e em bancos de dados Oracle, SQL Server e DB2 na plataforma aberta, por exemplo.

Não raro, empresas que possuem cenários como este (seja lá por qual motivo for), também possuem aplicações desenvolvidas em C, VB6, ASP, ASP.NET, Java etc.

Ou seja, os dados da empresa não podem depender de uma ou outra tecnologia, pois eles são da corporação, não de um ou outro sistema. Esse, aliás, sempre achei o problema da maioria das empresas que conheci.

SOA é uma abordagem interessante, mas acho vai muito além da discussão que se afigura com este post. = )

Já ouvi de muita gente que os dados nascem depois e para apoiar o desenho de um sistema. Mas, particularmente, esse é um cenário desconhecido por mim. Na contramão dessas pessoas, sempre achei que ORM deveria ser utilizado quando a produtividade precisasse ser mais alta que o desempenho do produto final. Mesmo assim, já tendo o banco de dados já desenhado.

no site


julho 6. 2009 14:33
Rafael Noronha
Fernando,

ORM não resulta apenas em aumento de produtividade e não necessariamente gera redução considerável de performance.

Além disto um banco de dados pode ser corretamente desenhando independente de estar ou não associado ao desenvolvimento de um sistema.

http://rafanoronha.net/http://rafanoronha.net/


Brazil Eduardo Costa
julho 8. 2009 23:18
Eduardo Costa
Muito bom artigo!
Inclusive fui atras de mais informações sobre DDD + NH fluente + linq e achei fantástico as possibilidades. Não perde em nada para o EF, é só criar um gerador de código para as entidades e as classes de mapeamento que você tem uma ferramenta ORM melhora que o EF.

no site


Brazil Fluent
outubro 15. 2009 10:51
Fluent
Legal o artigo. Fiz uns testes, sendo que qual versão do Fluent foi usada no exemplo? Pois alguns métodos mudaram na versão RTM 1.0.

no site


outubro 15. 2009 15:11
Giovanni Bassi
A versão era beta... algumas coisas mudaram mesmo.

http://unplugged.giggio.net/http://unplugged.giggio.net/

Comentar


(Vai mostrar seu Gravatar)

  Country flag

biuquote
  • Comentário
  • Pré-visualização
Loading



Quem é Giovanni Bassi

Giovanni Bassi Sou uma pessoa apaixonada por tecnologia e especificamente por .Net. Sou consultor independente especialista em .Net, focado em arquitetura e melhores práticas. Tenho dezenas de artigos publicados na .Net Magazine, revista da qual sou editor técnico. Ministro palestras e cursos de vez em quando, e quando dá tempo eu respiro um pouco. Mais detalhes nesta página.

Busca

Selos

Eu vou ao TechEd Brasil 2010, e você?

MVP

MCPD

MCSD

.Net Magazine

Abaixo ao if!

Calendário

«  setembro 2010  »
seteququsedo
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910
Ver detalhamento de posts no calendário

Blogs interessantes

    OPMLDownload OPML file

    Postagens recentes

    Comentários recentes

    Disclaimer / Aviso
    As opiniões colocadas neste blog são minhas e pessoais e não expressam necessariamente as opiniões de meus empregadores, pareceiros e amigos. Da mesma forma, os comentários feitos por leitores do blog não expressam a minha opinião.

    © Copyright 2010 .Net Unplugged
    Log in