Resolver problemas com Reflection (C#)

Num dos nossos produtos “flagship”, que é composto por vários módulos, temos aquilo a que podemos chamar “namespace nightmare” se não houver documentação e o pessoal não andar atento. Basicamente cada módulo tem o seu namespace próprio e dentro de cada módulo, cada layer tem o seu namespace. A aplicação segue o padrão comum das 3 layers, pelo que o q acontece é algo do género:

Modulo1.GUI
Modulo1.BLL
Modulo1.DAL

Modulo2.GUI
Modulo2.BLL
Modulo2.DAL

Modulo3.GUI
Modulo3.BLL
Modulo3.DAL

Existem alguns interfaces comuns, que especificam as funcionalidades que todos os serviços, por exemplo, devem apresentar para haver uma certa coerência nas implementações das funçoes comuns (Save, Get, Search, Dispose, etc.) a todos os serviços. As interfaces são, obviamente, contratos.

Nota: os serviços são as classes da layer BLL, que tratam da lógica de negócio do sistema e não serviços WCF ou web services SOPA ou algo semelhante.

Sempre mantivemos isto sem referências circulares o que nos colocou alguns desafios. Nomeadamente em relação à partilha de informação e, mas “bicudo” de funcionalidades e serviços. Assim, decidimos confiar na “magia” do Reflection para ajudar nestes casos. Criamos alguns métodos auxiliares que nos permitem utilizar os serviços em qualquer ponto do sistema, mesmo quando uma referência directa não é possível. 

Com este post, pretendo mostrar o que foi criado em termos genéricos e o que se pretendeu atingir.

Problema 1 – Como utilizar as funções “Search” de um serviço sempre que necessário ?

A solução é simples de encontrar e simples de implementar, desde que se tenha um conhecimento normal da framework. Assim, foi criado um método que o que faz é criar e devolver ao caller uma instância do serviço pedido.
public static IService GetServicoPeloNome(string modulo, string nomeServico)

{

// Carregar o assembly onde se encontra o serviço

System.Reflection.Assembly myAssembly = System.Reflection.Assembly.LoadFrom(string.Format(@"{0}\{1}.BLL.dll"

, Application.StartupPath

, modulo));

 

// Obter o tipo do serviço

Type myType = myAssembly.GetType(string.Format("{0}.BLL.{1}", modulo, nomeServico));

 

// Obter e retornar a instância

return (IBusinessService)(myType.InvokeMember(nomeServico, System.Reflection.BindingFlags.CreateInstance, null, new object(), null));

}

Com este método, conseguimos obter instâncias de qualquer serviço do sistema, desde que o mesmo implemente o interface IService. Obviamente que só nos permite depois chamar os métodos que são definidos pelo Interface, mas é essa a ideia.


Obviamente, isto não é o “real martelo dourado” e não se pode tratar tudo como um prego. Daí que recentemente me surgiu a necessidade de criar um outro método, com outra finalidade. No entanto, recorri de novo ao Reflection.

Problema 2 – Como invocar, de um determinado serviço com interface conhecido, um método que não é definido pelo interface ?

Mais uma vez, a solução é simples. Neste caso obtemos uma instância do serviço recorrendo ao Activator e depois invocamos um método dessa mesma instância, retornando o resultado do mesmo. É uma solução bastante genérica e, penso eu, bastante elegante:
public static object InvokeMetodoServico(string assembly, string fullNamespace, string metodo, object[] argumentos)

{

// Carregar o assmebly que contém o serviço

System.Reflection.Assembly myAssembly = System.Reflection.Assembly.LoadFrom(assembly);

// Obter o tipo do serviço

Type servicoType = myAssembly.GetType(fullNamespace);

// Criar uma instância do serviço (todos os serviço implementam IDisposable, por isso a utilização da keyword "using"

using (IBusinessService servico = Activator.CreateInstance(servicoType) as IBusinessService)

{

// Invocar o método e devolver o resultado do mesmo

return servicoType.InvokeMember(metodo, System.Reflection.BindingFlags.InvokeMethod, null, servico, argumentos);

}

}

No entanto, existe um senão com esta abordagem. Se o desenvolvimento for feito por equipas “estanques”, digamos que quem desenvolve o módulo 1 sabe pouco ou nada sobre o módulo 2 e precisar de algo do módulo 2 e naõ existir referência directa, das duas, uma: ou existe documentação de qualidade ou tem haver muita comunicação de qualidade entre as equipas.

Se tiverem opiniões ou reparos a fazer, força nisso. Sou todo ouvidos. Quer dizer, mais ou menos…

De volta…

Cá estou eu, de volta das férias. Perspectivam-se 4 meses até ao final do ano bastante duros. Vão continuar os apertos de cinto e as medidas de combate ao défice.

Vão ser 4 meses de “assalto” mental e de proliferação de stress. O trânsito vai ser ainda pior que o normal, com os a serem ainda mais irresponsáveis na estrada que o “normal”, devido ao stress e a muitos deles usarem a estrada como escape.

O que vale é que há futebol. Liga, selecção, champions, liga europa. E o “pobão” mantém-se mais ou menos contente, haja bola.

Com a chegada de 2012, não deve mudar muita coisa, mas ao menos é outro ano, com novas possibilidades. :)

Quanto a mim, a ideia é continuar a olhar em frente porque atrás vem gente…Já diz o mesmo a minha avó. :)

Férias – A montanha espera-me

PNPG terrasdebouro

Image via Wikipedia

Está a chegar o meu segundo período de férias para este ano (2011). Desta feita vamos, mais uma vez, até uma das zonas que mais gosto do nosso jardim à beira-mar plantado: Gerês, nomeadamente Terras de Bouro.

Vai servir para recarregar baterias, respirar ar mais puro, dar uns mergulhos e relaxar. Já me faziam falta.

Vemo-nos daqui a uns dias…

Facto curioso acerca da Língua Portuguesa e o WordPress

PortugalMeio sem querer, numa onda de “cusquice” pura, dei com esta informação interessante, a respeito das línguas mais escritas em sites hospedados no WordPress. O TOP 10 é o seguinte:

  1. English 66%
  2. Spanish 8.7%
  3. Portuguese 6.5%
  4. Indonesian 3.5%
  5. Italian 2%
  6. German 1.8%
  7. French 1.4%
  8. Russian 1.1%
  9. Vietnamese 1.1%
  10. Swedish 1.0%
Podem consultar outras estatísticas aqui,

Novo “poiso”

Olá a todos,

Devido a uma série de mudanças na minha vida nos últimos tempos, acabei por ter de por o 8 minutos-luz em segundo plano. Procurei diversas soluções para o reavivar e acabei por decidir usar os serviços do WordPress.Com para já. No futuro logo se verá o que espera este blog.

Desde já vou tentar ser mais recorrente a escrever, e os temas serão, como sempre, generalistas e mediante o que me for na alma.

Espero encontrar-vos por aí. :)

O autor do blog, Nuno "Stargazer" Coimbra

O autor do blog, Nuno "Stargazer" Coimbra

O autor do blog, Nuno “Stargazer” Coimbra

O astropt passou o milhão de posts!

Há usn tempos escrevi sobre o aniversário do astropt. Desta vez quero assinalar o milhão de posts! Kudos, astroPT!!

Pinto da Costa no seu melhor

Poderia escrever muito, mas não vale a pena. Vejam o video. :mrgreen:

astroPT de Parabéns – 3 anos!

Pois é, o projecto de divulgação cientifica on-line astroPT, do qual faço orgulhosamente parte desde a génese, está de parabéns. Ontem, dia 21 de Abril completou 3 anos. Foram 3 anos de crescimento sustentado, de milhares de posts, noticias em praticamente primeira mão sobre diversos temas ligados à ciência, principalmente às ciências espaciais.

Como forma de comemorar a data, o nosso “colaborador mor” em termos de posts publicados, reuniu o TOP 100 de posts mais populares do blog. Verão que é uma leitura interessante.

Fã de Star Wars? Fã da LEGO ? Então vê isto!

Se és um fã da saga Star Wars e um fã da LEGO, deves saber que a marca de blocos para brincar e construir, tem uma colecção dedicada a este Universo. Tive acesso a um vídeo que foi feito para um concurso de um website. Penso que todos concordaremos que está demais!

E esta? Barack Obama prémio Nobel da Paz

Grande surpresa, pelo menos para mim. O homem tá “fresquinho” na cena mundial e já recebe um destes? Vamos ver de que vai servir. Não é que não entenda os motivos do comité, mas acho que ninguém, nem mesmo o próprio Barcak contavam com isto.

Podem ler mais aqui.

Seguir

Get every new post delivered to your Inbox.