Semana de acontecimentos
Esta semana passou rápido. Tivemos o TechEd em São Paulo e foi muito bom ver o evento tendo grande aceitação, principalmente quanto ao conteúdo técnico. O Danilo e o Rogério fizeram um trabalho excelente de coordenação e todo o time de track owners e palestrantes não fizeram por menos. Para mim, a única baixa foi ainda a pequena participação do público feminino de TI. Não sei como podemos influenciar nisto, mas a verdade é que perdemos muito com a diminuição na diversidade de pensamento e cultura.
Outra: Markus Christen chegou para nos ajudar falando de arquitetura de infra-estrutura. Seu blog já está no ar em https://blogs.technet.com/markuschristen . Como o Gebara resolveu abraçar outros temas (ver), o Markus chega para trazer a sua experiência de anos como consultor. Ele vai errar um pouco no português, pois sua origem suíça ainda o faz confundir o gênero dos nossos substantivos, mas seu conhecimento e experiência vão nos ajudar muito a esclarecer os caminhos da arquitetura para a infra-estrutura. Muito bem vindo, Markus!
Steve Ballmer esteve aqui e deu uma excelente apresentação no TechEd. Falou da necessidade de uma TI ágil e reafirmou que S+S, virtualização, interoperabilidade, segurança e experiência do usuário se tornaram a base para os novos desenvolvimentos na nossa área (leia em https://www.microsoft.com/presspass/exec/steve/2008/10-14TechEdBrazil.mspx). Estive em outras conversas com ele também, e é impressionante a sua energia, amplitude e clareza.
Por fim, muita gente no TechEd pediu o código que apresentei sobre Entity Framework e desenvolvimento em N camadas. Bem, a base está no artigo do John Papa. Minhas mudanças no código do artigo foram as seguintes:
1) No Façade dos serviços incorporar transação e liberação dos contextos do Entity Framework. Exemplo:
public List<Customer> FindCustomerList(string companyName)
{
List<Customer> lCustomer = null;
using (TransactionScope transaction = new TransactionScope()) {
try {
lCustomer = new CustomerManager().FindCustomerList(companyName);
EFExtension.SaveAllContexts();
transaction.Complete();
}
catch (Exception ex) {
// dispose nos ObjectContext
throw ex;
}
finally {
// Dispose all Contexts
EFExtension.DisposeAllContexts();
}
}
return lCustomer;
}
2) Incluir na biblioteca de apoio um conjunto de funções que administram contextos visando ter um singleton para cada contexto numa thread:
// Insere contexto no dicionário da thread para criar um singleton
public static void SetContext(string ctxName, ObjectContext ctx) {
Dictionary<string, ObjectContext> ctxDict =
Thread.GetData(Thread.GetNamedDataSlot("ContextDictionary")) as Dictionary<string, ObjectContext>;
if (ctxDict == null) {
ctxDict = new Dictionary<string, ObjectContext>();
Thread.SetData(Thread.GetNamedDataSlot("ContextDictionary"), ctxDict);
}try {
ctxDict.Add(ctxName, ctx);
} catch ( Exception ex ) {
ctx.Dispose(); // dispose it if a copy already exists
}
}// Retorna contexto do dicionário da thread
public static ObjectContext GetContext(string ctxName) {
Dictionary<string, ObjectContext> ctxDict =
Thread.GetData(Thread.GetNamedDataSlot("ContextDictionary")) as Dictionary<string, ObjectContext>;
if (ctxDict == null ) {
ctxDict = new Dictionary<string, ObjectContext>();
Thread.SetData(Thread.GetNamedDataSlot("ContextDictionary"), ctxDict);
}ObjectContext ctx;
try {
ctxDict.TryGetValue(ctxName, out ctx);
} catch ( Exception ex ) {
return null;
}
return ctx;
}// Salva todos os contextos das threads
public static void SaveAllContexts() {
Dictionary<string, ObjectContext> ctxDict =
Thread.GetData(Thread.GetNamedDataSlot("ContextDictionary")) as Dictionary<string, ObjectContext>;
if (ctxDict == null)
return;
foreach (ObjectContext ctx in ctxDict.Values) {
ctx.SaveChanges();
}
}// Libera todos os contextos das threads
public static void DisposeAllContexts() {
Dictionary<string, ObjectContext> ctxDict =
Thread.GetData(Thread.GetNamedDataSlot("ContextDictionary")) as Dictionary<string, ObjectContext>;
if (ctxDict == null)
return;
foreach (ObjectContext ctx in ctxDict.Values) {
ctx.Dispose();
}
Thread.SetData(Thread.GetNamedDataSlot("ContextDictionary"), new Dictionary<string, ObjectContext>());
}
3) Nas regras de negócio, garantir o uso do singleton através dos métodos acima. Exemplo:
public class CustomerManager
{
private const string ctxName = "ctxCustomerManager";public CustomerManager()
{
if ( EFExtension.GetContext(ctxName) == null )
EFExtension.SetContext(ctxName, new NorthwindEFEntities() );
}public List<Customer> FindCustomerList(string companyName)
{
NorthwindEFEntities context = EFExtension.GetContext(ctxName) as NorthwindEFEntities;var q = from c in context.CustomerSet
where c.CompanyName.StartsWith(companyName)
select c;
return q.ToList();
}...
Abraço a todos.
Comments
Anonymous
October 19, 2008
Olá Otavio Primeiramente, meus parabens pelo show de palestra dada no TechEd, tive a felicidade de acompanhar tua apresentação. Quanto ao conteúdo exposto, tenho duas duvidas: 1 - O Entity Framework ainda encontra-se em beta 3 ou já existe uma versão em produção? 2 - Existe algum complemento a ser instalado no VS2008 para permitir a a execucao do artigo apresentado pelo John Papa?Anonymous
October 21, 2008
Salve, Marlon. Obrigado pelo apoio.Vamos às perguntas:
- O EF foi lançado junto com o SP1 do .Net Framework 3.5. Portanto, versão de produção.
- O Artigo do John Papa foi implementado com o Beta 2. Se não me engano, fiz alguns pequenos ajustes para fazê-lo funcionar no release final. Creio que recriei o edm e mudei os nomes das coleções (no final, as coleções terminam em "Set"). Não fiz muito mais que isto. Se tiver dificuldades, me fala. Abraços, Otavio
- Anonymous
December 22, 2008
Olá pessoal, tudo certo? Esse assunto tem sido recorrente desde julho, retornando em algumas discussões