NHibernate - Apresentando e usando o ActiveRecord


Neste artigo eu vou dar uma introdução básica sobre o ActiveRecord e mostrar como usar este recurso para gerar os arquivos de mapeamento objeto relacional (OR/M) no NHibernate.

Se você não conhece o NHibernate sugiro que leia o meu artigo VB .NET - Usando o NHibernate onde eu dou uma introdução básica sobre esta ferramenta e mostro como usá-la em um exemplo prático.

Apenas para lembrar o NHibernate é a versão para a plataforma .NET do framework de persistência Hibernate desenvolvido para a plataforma Java. Ele é um projeto open source e pode ser usado para gerar o mapeamento objeto relacional para diversos bancos de dados. Uma das suas principais vantagens e não ter que escrever as instruções SQL pois todos os comandos para persistência são gerados em tempo de execução.

Atualmente a comunidade tem discutido muito sobre a utilização de ferramentas OR/M , ou seja, ferramentas que realizam o mapeamento objeto relacional. Existem dezenas de ferramentas que se propõe a realizar este serviço e, para a comunidade .NET, atualmente o NHibernate é uma das ferramentas mais usadas e mais maduras do mercado.

A Microsoft lançou recentemente o Entity Framework que tem o mesmo propósito, mas a ferramenta esta evoluindo e ainda não atingiu o nível de maturidade que os desenvolvedores estão esperando. (A próxima versão da plataforma .NET trará uma versão mais madura da ferramenta,vamos aguardar...)

Embora o NHibernate seja uma ferramenta consagrada e muito usada ela tem um problema: dá um trabalho danado gerar os arquivos de mapeamento XML na mão.

É aqui que entra o ActiveRecord um projeto Castle que é uma implementação do padrão de projeto ActiveRecord que consiste em instanciar propriedades que representam um registro de um banco de dados. Com o ActiveRecord não há necessidade de configurar arquivos xml para criar os mapeamentos do Nhibernate

O padrão active record (em inglês: active record pattern) é um padrão de projeto encontrado frequentemente em um software que guarda dados em banco de dados relacionais. Foi nomeado por Martin Fowler no seu livro Patterns of Enterprise Application Architecture.

Active Record é uma abordagem para acessar dados em um banco de dados. Uma tabela do banco de dados ou view é envolta em uma classe, desta maneira, uma instância é vinculada a uma única linha (registro) na tabela. Após a criação de um objeto, um novo registro é adicionado na tabela após salvar. Qualquer objeto carregado obtém informações do seu banco de dados; quando um objeto é atualizado, o registro correspondente na tabela também é atualizado. A classe wrapper implementa os métodos de acesso ou propriedades para cada coluna na tabela ou view.

Este padrão é comumente usado por ferramentas de persistência de objetos, e em mapeamento objeto-relacional. Normalmente relacionamentos de chave estrangeira serão expostos como um objeto de tipo apropriado por meio de uma propriedade.

O Castle ActiveRecord é uma implementação deste padrão e neste artigo eu vou mostrar como usar o ActiveRecord da Castle para gerar os arquivos de mapeamento XML necessários em uma aplicação Windows Forms que utiliza o NHibernate como ferramenta OR/M.

Requisitos necessários

No exemplo prático que irei mostrar neste artigo vamos precisar das seguintes ferramentas:

ActiveRecord

NHIbernate

Após fazer o download você deve descompactar os arquivos em uma pasta própria.

SQL Server 2005

Management Studio Express Edition

Para poder usar os recursos do ActiveRecord e do NHiberante você terá que incluir as seguintes referências no projeto.

Para fazer isso clique sobre o nome do projeto e selecione Add Reference;

A seguir selecione Browse e localize as seguintes DLLs  referente ao ActiveRecord selecionando-as :

Castle.ActiveRecord.dll
Castle.Core.dll
Castle.Components.Validator.dll
Castle.DynamicProxy.dll

Repita o processo e agora selecione as DLLs referente ao NHibernate:

NHibernate.dll
Iesi.Collections.dll
log4net.dll

Após concluída esta etapa você deverá declarar o seguinte namespace na classe do seu projeto:

C#

VB .NET

using Castle.ActiveRecord        Imports Castle.ActiveRecord

O objetivo principal do artigo é mostrar como usar o ActiveRecord para gerar os arquivos de mapeamento XML este conceito não vai ser detalhado no artigo portanto sugiro que você leia o artigo que explica este detalhes.

Com o ActiveRecord você não vai precisar aprender sobre o esquema de mapeamento do NHibernate para poder gerar os seus arquivos XML nem vai ter que tratar com ISession e ISessionFactory pois toda esta complexidade e tratada pelo ActiveRecord.

O ActiveRecord oferece um subconjunto das funcionalidades de mapeamento do NHibernate sendo que o mapeamento é feito usando classes , campos e atributos a nível de propriedade. (O ActiveRecord esta apto a infereir os nomes da tabela e das colunas mesmo que forem omitidas)

Obs: O Ruby On Rails manuseia dados usando o Active Record, que faz o trabalho de ORM.

Abaixo temos um exemplo de uma classe criada para gerar o mapeamento usando o ActiveRecord através de atributos:

using Castle.ActiveRecord;

[ActiveRecord]
public class Category : ActiveRecordBase
{
    private int id;
    private string name;
    private Category parent;
    private IList<Category> subcategories = new List<Category>();

    [PrimaryKey]
    public int Id
    {
        get { return id; }
        set { id = value; }
    }

    [Property]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    [BelongsTo("parent_id")]
    public Category Parent
    {
        get { return parent; }
        set { parent = value; }
    }

    [HasMany]
    public IList<Category> SubCategories
    {
        get { return subcategories; }
        set { subcategories = value; }
    }
}
 
Neste exemplo, os atributos HasMany e BelongsTo podem ser usados em uma classe pai e filho, respectivamente, para indicar uma relação um-para-muitos.

O ActiveRecord atua sobre o que é chamado de tipos ActiveRecord que são classes que usam o atributo ActiveRecordAttribute e herdam a partir de uma das classes base ActiveRecord. Atualmente a classe base é a classe ActiveRecordBase que é uma classe genérica.

O atributo ActiveRecord é usado para definir uma classe como um tipo ActiveRecord e e para associar a a informação do mapeamento.

No exemplo acima vemos isso no trecho de código:

using Castle.ActiveRecord;

[ActiveRecord]
public class Category : ActiveRecordBase
{
......

Uma outra forma seria informar o nome da tabela:

using Castle.ActiveRecord;

[ActiveRecord("Category")]
public class Category : ActiveRecordBase
{
......

No exemplo acima não informado de forma explicita o nome da tabela nem o esquema do banco de dados , neste caso o ActiveRecord então assume a classe Category como a classe que esta sendo mapeada para a tabela do banco de dados com o mesmo nome. Neste caso o esquema do banco de dados será nulo.

Para informar o nome da tabela e do esquema do banco de dados usamos as propriedades Table e Schema conforme abaixo:

using Castle.ActiveRecord;

[ActiveRecord(Table="Category", Schema="dbo")]
public class Category : ActiveRecordBase
{
......

Antes de utilizar o ActiveRecord em tempo de execução você precisa inicializar de forma apropriada o Framework uma única vez para o tempo de vida da aplicação.

Afim de inicializar o framework, você precisa fornecer as seguintes informações:

Opcionalmente você também pode ativar o debug, o caching e efetuar outra configurações.

Antes de usar o ActiveRecord sua aplicação precisa invocar o método Initialize da classe ActiveRecordStarter para realizar a inicialização do framework.

O método Initialize precisa da implementação da interface IConfigurationSource e da definição dos tipos de ActiveRecords (que são as classes do domínio) a serem examinadas, dessa forma o NHibernate é configurado para examinar os tipos para erros de sintaxe e para construir o mapeamento para todos tipos definidos.

A seguir temos um exemplo de como efetuar tal tarefa para duas classes usando a linguagem C#:

using Castle.ActiveRecord;

IConfigurationSource config = ActiveRecordSectionHandler.Instance ;
ActiveRecordStarter.Initialize(config, typeof(Classe1), typeof(Classe2));
...

A classe ActiveRecordSectionHandler faz a leitura da configuração a partir de uma entrada para um 'activerecord' no arquivo xml associado com a AppDomain;

Outra forma de realizar a mesma tarefa é obter a informação da configuração de um arquivo AppConfig.xml;

imports  Castle.ActiveRecord;

Dim
source As XmlConfigurationSource = New XmlConfigurationSource("AppConfig.xml")
ActiveRecordStarter.Initialize(source,
GetType(Category))
.....

A classe que deve ser criada para realizar o mapeamento deve herdar da classe abstrata ActiveRecordBase que expõe membros públicos e protegidos que provavelmente você vai usar na sua classe ActiveRecord. Abaixo temos um exemplo de utilização da classe para gerar o mapeamento:

VB .NET

Imports Castle.ActiveRecord
 

<ActiveRecord("Contatos")> _

Public Class Contato

       Inherits ActiveRecordBase(Of Contato)

 

Private m_id As Integer

 

<PrimaryKey("ID")> _

Public Property Id() As Integer

Get

     Return (m_id)

End Get

Set(ByVal value As Integer)

      m_id = value

End Set

End Property
.....

 

A classe ActiveRecord também expõe também instâncias de membros para Save, Create, Update e Delete sendo que a operação Save esta apta a distinguir se a classe precisa ser criada ou atualizada.

Você pode consultar mais detalhes na documentação do ActiveRecord: http://www.castleproject.org/activerecord/documentation/v1rc1/index.html

Usando o ActiveRecord e o NHibernate em uma aplicação Windows Forms

Para que você possa entender como  implementar a utilização dos recursos do ActiveRecord em sua aplicação C# ou VB .NET eu vou criar um exemplo usando a linguagem VB .NET no qual iremos realizar as seguintes tarefas:

Aguarde na continuação deste artigo a criação do projeto completo usando NHibernate e ActiveRecord...

Referências:


José Carlos Macoratti