none
Padrão Strategy em várias dlls RRS feed

  • Pergunta

  • Estou implementando um 'adaptador' para o PAF que será usado por vários programas de nossa empresa. Este projeto deverá fazer a comunicação entre os sistemas e um programa de PDV que outro desenvolvedor está fazendo. A idéia é que cada desenvolvedor implemente um IRepositorioProduto, IRepositorioCupom e outras classes próprias de cada sistema. Estas classes serão usadas pelo PDV.

    Como posso fazer um factory para que o programa do PDV instancie o tipo certo dependendo de um parâmetro passado pelo método Main ou algo assim. É importante saber que o mesmo cliente pode ter dois sistemas na mesma máquina, resultando em duas dlls diferentes.

    Não gostaria de colocar as implementações de todos os sistemas na mesma dll.
    +.+
    terça-feira, 23 de fevereiro de 2010 11:59

Respostas

  • Davi,

    A resposta é Reflection. Vc carrega o assembly dinamicamente, carrega o tipo e instancia o tipo.

    Outra saída seria com um container de injeção de dependência. No exemplo abaixo, dá uma idéia disso, por "configuração", vc seleciona o assembly e a classe:


    Uma observaçõa importante sobre o reflection, é que até a framework 3.5, existe toda a infra-estrutura para carregar um assembly dinamicamente, dentro de um dado AppDomain, porém, não existe forma de descarregar!!!

    Eu já tive alguns probleminhas com isso, mas na 4.0 tá resolvido.


    Abraço,

    Eric
    terça-feira, 23 de fevereiro de 2010 16:10
  • Davi acredito que se você implementar uma abstract factory você terá uma solução pro seu problema. Como você mesmo disse, existirão as interfaces  IRepositorioProduto, IRepositorioCupom etc. Essas interfaces podem amarrar a implementação de produtos reais, como RepositorioProduto e RepositorioCupom. Você só precisa implementar as factories que saibam fabricar esses produtos e por reflection você pode dizer qual factory usará (esta informação pode por exemplo estar no config da aplicação).

    http://pt.wikipedia.org/wiki/Abstract_Factory pode te dar uma idéia do que estou falando.

    Att,
    Adolfo Pacheco


    Att, Adolfo Pacheco
    terça-feira, 23 de fevereiro de 2010 17:42
  • Pronto. Não tive a oportunidade de implementar ainda, mas pra ficar de ajuda pra quem precisar farei da seguinte forma.

    lerei melhor este tópico
    http://social.msdn.microsoft.com/forums/pt-BR/vscsharppt/thread/cea80780-96f2-464f-9e1b-8feb425a0ab4/

    Criarei no Main do meu programa de PDV um parâmetro do tipo string que conterá o nome da dll contendo a estratégia.

    Usarei var meuAssembly = Assembly .LoadFrom( caminhoDll );
    Depois      Aplicacao.FabricaRepositorios = meuAssembly.CreateInstance( "Namespace.FabricaRepositorio" , false , BindingFlags .CreateInstance, null , null , null , null );

    Depois vai ser só curtição >:D
    +.+
    terça-feira, 23 de fevereiro de 2010 22:18

Todas as Respostas

  • Nao sei se captei todo o ambiente, mas me parece que vc no assunto da thread ja deu a resposta.

    Sem saber se é esse mesmo a direcao da comunicacao, eu acho que seja necessario saber qual o tipo certo mas sim receber uma instancia que implemente as coisas dos seus repositorios. Ai caberia a cada implementacao sua logica.
    Repito, nao tenho certeza se sao essas as direcoes e as responsabilidades mas foi o q eu entendi
    Gustavo Rocha, MCTS, MCPD, CSM, Arquiteto de Software - http://subindoaladeira.wordpress.com/
    terça-feira, 23 de fevereiro de 2010 13:04
  • Davi,

    A resposta é Reflection. Vc carrega o assembly dinamicamente, carrega o tipo e instancia o tipo.

    Outra saída seria com um container de injeção de dependência. No exemplo abaixo, dá uma idéia disso, por "configuração", vc seleciona o assembly e a classe:


    Uma observaçõa importante sobre o reflection, é que até a framework 3.5, existe toda a infra-estrutura para carregar um assembly dinamicamente, dentro de um dado AppDomain, porém, não existe forma de descarregar!!!

    Eu já tive alguns probleminhas com isso, mas na 4.0 tá resolvido.


    Abraço,

    Eric
    terça-feira, 23 de fevereiro de 2010 16:10
  • Nao concordo que seja A resposta.

    É UMA resposta. Nao necessariamente ele precisa carregar por reflection pelo fato de estar em outra dll. Em momento algum ele disse que nao poderia fazer referencia as dlls. Ele pode separar as interfaces em um assembly e as implementacoes em outro. E se tiver referencia, nao precisa ser reflection. Ele mantem um baixo acoplamento( com limite ) e separacao de logica.

    injecao de dependencia é sem duvida uma solucao, mas o grande lance é saber se ele pode escapar de um laço de decisao de quem instanciar. Por isso eu comentei que a ordem das chamadas na solucao faz diferenca.


    Gustavo Rocha, MCTS, MCPD, CSM, Arquiteto de Software - http://subindoaladeira.wordpress.com/
    terça-feira, 23 de fevereiro de 2010 16:43
  • Davi acredito que se você implementar uma abstract factory você terá uma solução pro seu problema. Como você mesmo disse, existirão as interfaces  IRepositorioProduto, IRepositorioCupom etc. Essas interfaces podem amarrar a implementação de produtos reais, como RepositorioProduto e RepositorioCupom. Você só precisa implementar as factories que saibam fabricar esses produtos e por reflection você pode dizer qual factory usará (esta informação pode por exemplo estar no config da aplicação).

    http://pt.wikipedia.org/wiki/Abstract_Factory pode te dar uma idéia do que estou falando.

    Att,
    Adolfo Pacheco


    Att, Adolfo Pacheco
    terça-feira, 23 de fevereiro de 2010 17:42
  • Gustavo, no assunto da thread ja dei a resposta para o problema sim, mas não sei como fazer para referenciar as dlls certas, pois não vou ter todas disponíveis a todo tempo. Para o programa A vou ter a dll A.dll para o B, B.dll e assim vai. O PDV vai usar as classes que como você falou sabem das responsabilidades através das interfaces de repositório.

    Na prática todo o esquema ja está feito. Em uma solução com vários projetos. Meu problema é com a estrutura física dos arquivos e não com a arquitetura em si. No cliente do programa do PDV fiz um abstract factory que tem métodos para instanciar todos os tipos comuns entre os dois sistemas de acordo com o sistema, mas não sei se seria melhor usar IoC para isto.

    Enfim, falando sobre o problema de estrutura...

    Os sistemas que são usar este PDV são em VB6 e .NET, o sistema do vb6 chamaria o aplicativo de pdv passando como parâmetro do método Main o nome do processo do sistema(não sei se o nome é o mais adequado...) a partir deste nome, vou decidir qual abstract factory instanciar. O difícil, é que as implementações do abstract factory está em cada uma das dlls. Como vou chamá-las? Reflection é uma boa idéia, vou tentar e volto a postar os resultados.

    Obrigado pelas respostas, vocês são realmente ágeis ^^
    +.+
    terça-feira, 23 de fevereiro de 2010 18:38
  • Pronto. Não tive a oportunidade de implementar ainda, mas pra ficar de ajuda pra quem precisar farei da seguinte forma.

    lerei melhor este tópico
    http://social.msdn.microsoft.com/forums/pt-BR/vscsharppt/thread/cea80780-96f2-464f-9e1b-8feb425a0ab4/

    Criarei no Main do meu programa de PDV um parâmetro do tipo string que conterá o nome da dll contendo a estratégia.

    Usarei var meuAssembly = Assembly .LoadFrom( caminhoDll );
    Depois      Aplicacao.FabricaRepositorios = meuAssembly.CreateInstance( "Namespace.FabricaRepositorio" , false , BindingFlags .CreateInstance, null , null , null , null );

    Depois vai ser só curtição >:D
    +.+
    terça-feira, 23 de fevereiro de 2010 22:18