Usando o Castle ActiveRecord
.NET March 27th, 2008O Castle ActiveRecord é uma implementação do pattern Active Record desenvolvido em .NET em cima do NHibernate.
Ele faz parte do pacote de frameworks do projeto Castle Projet, e tem forte influencia da implementação do Active Record do framework Ruby On Rails.
Entre as muitas características dele vale destacar, a possibilidade de mapeamento de classes via atributos e não dos famigerados arquivos xml e um mecanismo de validação eficiente e flexível.
Criando o projeto
Acesse a página de download do projeto, baixe o arquivo Castle-net-2.0-release-2007-9-20.zip e descompacte em algum diretório da sua preferência.
Em seguida crie um novo projeto web e faça referência as assemblies abaixo:
Castle.ActiveRecord.dll
Castle.Core.dll
Castle.Components.Validator.dll
Castle.DynamicProxy.dll
NHibernate.dll
Iesi.Collections.dll
log4net.dll
Criando a tabela de Contatos
Crie uma base de dados chamada ContatosAR e em seguida crie uma tabela com a estrutura abaixo.
CREATE TABLE [dbo].[Contatos]( [Id] [int] IDENTITY(1,1) NOT NULL, [Nome] [varchar](255) NOT NULL, [Email] [varchar](255) NOT NULL, CONSTRAINT [PK_Contatos] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
Criando a classe Contato
Agora vamos criar a classe que vai representar a nossa tabela.
using System;
public class Contato
{
private int id;
private string nome;
private string email;
public int Id
{
get { return id; }
set { id = value; }
}
public string Nome
{
get { return nome; }
set { nome = value; }
}
public string Email
{
get { return email; }
set { email = value; }
}
}
Mapeando a classe Contato
Mapeando a nossa classe para o NHibernate. Só que em vez do xml entra em cena os atributos disponíveis no ActiveRecord.
[ActiveRecord("Contatos")]
public class Contato : ActiveRecordValidationBase<Contato>
{
private int id;
private string nome;
private string email;
[PrimaryKey(PrimaryKeyType.Native, "Id")]
public int Id
{
get { return id; }
set { id = value; }
}
[Property("Nome")]
[ValidateNonEmpty("Nome é requirido")]
[ValidateLength(1, 255, "Nome deve ter no máximo 255 caracteres")]
public string Nome
{
get { return nome; }
set { nome = value; }
}
[Property("Email")]
[ValidateNonEmpty("E-mail é requirido")]
[ValidateLength(1, 255, "E-mail deve ter no máximo 255 caracteres")]
[ValidateEmail("E-mail inválido")]
public string Email
{
get { return email; }
set { email = value; }
}
}
Configurando o ActiveRecord
No arquivo Web.Config adicione o código abaixo e altere a chave hibernate.connection.connection_string para apontar para a sua instância do SQL Server.
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="activerecord"
type="Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler, Castle.ActiveRecord" />
</configSections>
<activerecord isWeb="true">
<config>
<add key="hibernate.connection.driver_class"
value="NHibernate.Driver.SqlClientDriver" />
<add key="hibernate.dialect"
value="NHibernate.Dialect.MsSql2005Dialect" />
<add key="hibernate.connection.provider"
value="NHibernate.Connection.DriverConnectionProvider" />
<add key="hibernate.connection.connection_string"
value="Data Source=.;Initial Catalog=ContatosAR;Integrated Security=True" />
</config>
</activerecord>
</configuration>
E no arquivo Global.asax adicione o código abaixo.
<%@ Application Language="C#" %>
<%@ Import Namespace="Castle.ActiveRecord" %>
<%@ Import Namespace="Castle.ActiveRecord.Framework" %>
<%@ Import Namespace="Castle.ActiveRecord.Framework.Config" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
IConfigurationSource source = ActiveRecordSectionHandler.Instance;
ActiveRecordStarter.Initialize(source, typeof(Contato));
}
</script>
Listando os contatos
Agora, com o ActiveRecord configurado, vamos criar uma página para listar todos os contatos cadastrados na base de dados (nenhum até o momento).
<asp:GridView ID="gvContatos" AutoGenerateColumns="false" runat="server">
<Columns>
<asp:HyperLinkField DataNavigateUrlFields="Id"
DataNavigateUrlFormatString="EditarContato.aspx?Id={0}"
DataTextField="Nome" HeaderText="Nome" />
<asp:BoundField DataField="Email" HeaderText="E-mail" />
</Columns>
</asp:GridView>
ListarContatos.aspx.cs
public partial class ListarContatos : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
gvContatos.DataSource = Contato.FindAll();
gvContatos.DataBind();
}
}
Inserindo um contato
Montando o formulário de inserção. De propósito vou deixar para fazer a validação no servidor.
<h3>Novo contato</h3>
<asp:Panel ID="pnMensagem" runat="server" Visible="false">
<asp:Label ID="lblMensagem" runat="server" />
</asp:Panel>
<p>
<asp:Label ID="lblNome" runat="server" AssociatedControlID="txtNome">Nome:</asp:Label>
<asp:TextBox ID="txtNome" runat="server" Columns="40" MaxLength="255"></asp:TextBox>
</p>
<p>
<asp:Label ID="lblEmail" runat="server" AssociatedControlID="txtEmail">E-mail:</asp:Label>
<asp:TextBox ID="txtEmail" runat="server" Columns="40" MaxLength="255"></asp:TextBox>
</p>
<asp:Button ID="btnSalvar" runat="server" OnClick="btnSalvar_Click" Text="Salvar" />
ou <a href="ListarContatos.aspx">Voltar</a>
NovoContato.aspx.cs
public partial class NovoContato : System.Web.UI.Page
{
protected void btnSalvar_Click(object sender, EventArgs e)
{
pnMensagem.Visible = true;
lblMensagem.Text = "";
Contato contato = new Contato();
contato.Nome = txtNome.Text;
contato.Email = txtEmail.Text;
if (contato.IsValid())
{
contato.Create();
lblMensagem.Text = "Contato criado com sucesso.";
txtNome.Text = "";
txtEmail.Text = "";
}
else
{
foreach (string s in contato.ValidationErrorMessages)
lblMensagem.Text += s;
}
}
}
Editando um contato
<h3>Editar contato</h3>
<asp:Panel ID="pnMensagem" runat="server" Visible="false">
<asp:Label ID="lblMensagem" runat="server" />
</asp:Panel>
<p>
<asp:Label ID="lblNome" runat="server" AssociatedControlID="txtNome">Nome:</asp:Label>
<asp:TextBox ID="txtNome" runat="server" Columns="40" MaxLength="255"></asp:TextBox>
</p>
<p>
<asp:Label ID="lblEmail" runat="server" AssociatedControlID="txtEmail">E-mail:</asp:Label>
<asp:TextBox ID="txtEmail" runat="server" Columns="40" MaxLength="255"></asp:TextBox>
</p>
<asp:Button ID="btnSalvar" runat="server" OnClick="btnSalvar_Click" Text="Salvar" />
ou <a href="ListarContatos.aspx">Voltar</a>
EditarContato.aspx.cs
public partial class EditarContato : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Contato contato = Contato.Find(Convert.ToInt32(Request.QueryString["Id"]));
txtNome.Text = contato.Nome;
txtEmail.Text = contato.Email;
}
}
protected void btnSalvar_Click(object sender, EventArgs e)
{
pnMensagem.Visible = true;
lblMensagem.Text = "";
Contato contato = Contato.Find(Convert.ToInt32(Request.QueryString["Id"]));
contato.Nome = txtNome.Text;
contato.Email = txtEmail.Text;
if (contato.IsValid())
{
contato.Update();
lblMensagem.Text = "Dados do contato atualizados com sucesso.";
}
else
{
foreach (string s in contato.ValidationErrorMessages)
lblMensagem.Text += s;
}
}
}
Código do projeto
O código do projeto está disponivel para download.
Ele foi desenvolvido usando o Microsoft Visual Web Developer 2008 Express Edition com o SQL Server Express 2005.
Em breve
Depois dessa passada superficial vou tentar preparar uma série de posts detalhando mais as funcionalidades do framework.
Recent Comments