Refactoring/Indireção/DI - Vamos falar de código

44 views
Skip to first unread message

tucaz

unread,
Jul 28, 2010, 10:16:53 AM7/28/10
to .Net Architects
Oi!

Temos falado muito em testes e DI/IoC ultimamente, mas acabamos não
vendo código. Pra resolver isso tenho um problema que estou
enfrentando e queria os palpites de vocês.

Tenho duas classes: GeradorPedidos e Precificador. Para gerar um
pedido, minha classe precisa de uma instância de Precificador que é a
responsável por fornecer os preços dos produtos. Algo assim:

public class GeradorPedido
{
private IPrecificador _precificador;
public GeradorPedido(IPrecificador _precificador)
{
_precificador = precificador;
}

public void GerarPedido(Pedido novoPedido)
{
var total = 0;
foreach(var item in novoPedido.Itens)
{
total += _precificador.QuantoCusta(item);
}
//faz mais um monte de coisas
}
}

Esquema bem simples pra qualquer container de DI/IoC resolver. Peço
pro meu container uma instância da classe GeradorPedido e
automaticamente ele injeta uma nova instância da classe Precificador
do jeitinho que eu esperava.

Agora vem o problema...

Aparece um novo requisito que diz que o preço deve variar de acordo
com a loja, portanto Precificador depende agora também de loja:

public class Precificador : IPrecificador
{
private Loja _lojaFiltro;
public Precificador(Loja lojaFiltro)
{
_lojaFiltro = lojaFiltro;
}

public int QuantoCusta(Item itemAPrecificar)
{
//retorna o preço de acordo com a loja
if(_lojaFiltro.Codigo == 1)
return 10;
else if(_lojaFiltro.Codigo == 2)
return 20
else
return 30;
}
}

No entanto, eu só vou descobrir este valor em runtime, logo não posso
mais resolver essa dependência com container tão facilmente.

Uma opção seria criar uma AbstractFactory e injeta-la no GeradorPedido
que utilizaria a factory pra criar o Precificador passando o parametro
recebido em runtime. O único problema disso é que dessa forma o
GeradorPedido que não tem nada a ver com a história também vira
dependente da Loja, pois ele deve recebe-la pra poder passar para
factory.

Alguma outra sugestão?

Vinicius Quaiato

unread,
Jul 28, 2010, 10:57:09 AM7/28/10
to dotnetar...@googlegroups.com
Tuca,

Se você trabalhasse com isso não no nível do GeradorDePedido, mas no nível da aplicação. A aplicação sabe qual a loja, cria então(ou obtém) um Precificador para esta loja, e passa o precificador para o Gerador.

Na verdade acho que o Precificador nem deve conhecer a loja, mas talvez uma estratégia de preços por loja, algo assim.

por exmeplo:

//classe que coordena esse processo
public void ExecutarTodoEsseProcesso(Loja lojaSelecionada)
{
   //interface que o precificador conhece
   var estrategiaDePrecosPorLoja = FabricaDeEstrategiasDePreco(lojaSelecionada);

   var precificador = new Precificador(estrategiaDePrecosPorLoja);

   var geradorDePedido = new GeradorDePedido(precificador);
}

Assim você pode continuar usando o container para resolver o Gerador.


--
Você recebeu esta mensagem porque faz parte do grupo .Net Architects hospedado no Google Groups.
Para postar envie uma mensagem para dotnetar...@googlegroups.com
Para sair do grupo envie uma mensagem para dotnetarchitec...@googlegroups.com
Para mais opções visite o grupo em http://groups.google.com/group/dotnetarchitects?hl=pt-br

tucaz

unread,
Jul 28, 2010, 11:04:24 AM7/28/10
to .Net Architects
É esse o cenário mesmo Vinicius, mas não consigo ver uma forma de
passar isso pro container. Seu exemplo não está cobrindo o uso do
container.

On Jul 28, 11:57 am, Vinicius Quaiato <vinicius.quai...@gmail.com>
wrote:
> Tuca,
>
> Se você trabalhasse com isso não no nível do GeradorDePedido, mas no nível
> da aplicação. A aplicação sabe qual a loja, cria então(ou obtém) um
> Precificador para esta loja, e passa o precificador para o Gerador.
>
> Na verdade acho que o Precificador nem deve conhecer a loja, mas talvez uma
> estratégia de preços por loja, algo assim.
>
> por exmeplo:
>
> //classe que coordena esse processo
> public void ExecutarTodoEsseProcesso(Loja lojaSelecionada)
> {
>    //interface que o precificador conhece
>    var estrategiaDePrecosPorLoja =
> FabricaDeEstrategiasDePreco(lojaSelecionada);
>
>    var precificador = new Precificador(estrategiaDePrecosPorLoja);
>
>    var geradorDePedido = new GeradorDePedido(precificador);
>
> }
>
> Assim você pode continuar usando o container para resolver o Gerador.
>
> abraços,
>
> *Vinicius Quaiato*http://viniciusquaiato.com
>
> Twitter <vquaiato>
> [image: Google Talk/]vinicius.quai...@gmail.com [image: MSN/]
> vinicius.quai...@gmail.com
>
> 2010/7/28 tucaz <tuca...@gmail.com>
> > dotnetarchitec...@googlegroups.com<dotnetarchitects%2Bunsubscrib e...@googlegroups.com>

Vinicius Quaiato

unread,
Jul 28, 2010, 11:12:58 AM7/28/10
to dotnetar...@googlegroups.com
É vdd...

Mas, você precisa mesmo de um container nesse ponto específico? Pelo que vejo, o código está uando IoC e DI, só não está usando um container. 

Qual sua intenção em usar um container nesse caso?
2010/7/28 tucaz <tuc...@gmail.com>
É esse o cenário mesmo Vinicius, mas não consigo ver uma forma de

tucaz

unread,
Jul 28, 2010, 11:21:40 AM7/28/10
to .Net Architects
O container já existe. Estou mexendo em um código que criei
anteriormente e inclusive já existem alguns objetos que dependem de
GeradorPedido e outros que também dependem de IPrecificador.

A idéia de abstract factory é boa, mas traz a dependência pra todo
mundo que consome IPrecificador. Outra alternativa seria fazer injeção
por Property ou usar um método pra Inicializar a classe, mas não gosto
muito dessa idéia.

On Jul 28, 12:12 pm, Vinicius Quaiato <vinicius.quai...@gmail.com>
wrote:
> É vdd...
>
> Mas, você precisa mesmo de um container nesse ponto específico? Pelo que
> vejo, o código está uando IoC e DI, só não está usando um container.
>
> Qual sua intenção em usar um container nesse caso?
>
> > > > dotnetarchitec...@googlegroups.com<dotnetarchitects%2Bunsubscrib e...@googlegroups.com><dotnetarchitects%2Bunsubscrib

Thiago Alves

unread,
Jul 28, 2010, 11:27:45 AM7/28/10
to dotnetar...@googlegroups.com
Tuca, eu queria entender melhor seu problema.

Mais precisamente a seguinte frase:


"No entanto, eu só vou descobrir este valor em runtime, logo não posso
mais resolver essa dependência com container tão facilmente."

Abraço

2010/7/28 tucaz <tuc...@gmail.com>

Vinicius Quaiato

unread,
Jul 28, 2010, 11:41:35 AM7/28/10
to dotnetar...@googlegroups.com
Não sei se precisa de uma AbstractFactory Tuca.

Seu ponto é conseguir criar o GeradorDePedido, que agora depende de uma Loja que só é conhecida em runtime.

Isso está mais para um Builder. E eu abriria mão do container nessa situação. O builder recebendo uma Loja cria o seu Gerador.

Afinal o Gerado não muda por causa da loja, o que muda é o Precificador, por isso acho que não cabe uma abstract factory.

E sobre a dependência de outro sobre IPrecificador, utilizaria uma fábrica para eles, baseado na loja. E essa fábrica será também consumida pelo Builder.

Acho que o container vai dançar. Ou se alguém souber umas mágicas mais avançadas, manda aê.
2010/7/28 tucaz <tuc...@gmail.com>
O container já existe. Estou mexendo em um código que criei

Ricardo Simões

unread,
Jul 28, 2010, 11:50:36 AM7/28/10
to dotnetar...@googlegroups.com
Oi,

Só não concordo com o Vinicius em ter que criar um Builder para isso, uma fabrica de estratégias já seria suficiente para criar seu especialista na precificação.

Além do mais não estou entendendo porque o GeradorDePedido precisa de um container DI para ser criado.

Ele me parece ser um serviço especialista na função, e normalmente teremos um único especialista na função por domínio.

Digo isso, porque imagino que no seu domínio você não precise de um GeradorDePedidoDeCarros, GeradorDePedidosDeImoveis...

Ao que parece o container vai morrer mesmo...

[]'s

Ricardo Simões


2010/7/28 Vinicius Quaiato <vinicius...@gmail.com>

Vinicius Quaiato

unread,
Jul 28, 2010, 11:56:13 AM7/28/10
to dotnetar...@googlegroups.com
Então ricardo, eu disse um Builder por que pelo que entendi mais de um lugar usa o Gerador, e o gerador depende de um IPrecificador, que por sua vez depende de uma loja.

Para matar essa dependência com a loja, crio uma fábrica de EstratégiasDePrecificacao, e depois de obter passo a estratégia para o Gerador.

Na verdade o Builder seria para ocultar os passos da criação do Gerador apenas.

Ricardo Simões

unread,
Jul 28, 2010, 12:04:14 PM7/28/10
to dotnetar...@googlegroups.com
Oi, Vinicius,

Achei mesmo que tinha entendido seu conceito.

Contudo minha afirmação é realmente sobre o conceito da especialidade por domínio. Não consigo imaginar um domínio que precise de mais de um especialista na função de gerar pedidos.

Claro que o algoritmo de geração de pedido pode variar, como é o caso do nosso amigo tuca, entretanto não é necessário solicitar isto para um outro especialista na função, basta que ele saiba qual é o algoritmo de geração que precisa utilizar e dar o resultado desejado.

Por este motivo acredito que um Strategy mesclado com FactoryMethod e talvez um TemplateMethod resolva o problema.

Eu só iria considerar utilizar um container para os Precificadores, que aí sim pode haver a necessidade de consultar mais que um neste domínio.

felipe

unread,
Jul 28, 2010, 10:55:19 AM7/28/10
to .Net Architects
Fala moçada.

Meu primeiro post aqui na comunidade. Tenho muita experiência em
outras plataformas. Mas bora ver se consigo ajudar em forma de
analogia com Java. :P

No Java o Spring, container de DI/IoC mais utilizado tem a
possibilidade de receber uma indicação de qual factory ele usa pra
instanciar uma dependência.
Dessa forma, você poderia usar uma factory, como vc mesmo sugeriu, mas
ao invés de invocar a factory a partir do GeradordPedido, o container
de IoC invoca a Factory pra você. Logo, você não precisa de uma
instância de Loja no GeradorPedido.

Isso resolveria o seu problema, a minha pergunta agora é: Tem isso
em .NET? (Qual é o container de DI/IoC utilizado nesse caso?)

PS: Reforço que não manjo muito de .NET.

[]'s

Felipe

Victor Cavalcante

unread,
Jul 28, 2010, 12:11:31 PM7/28/10
to dotnetar...@googlegroups.com
Olhá quem está por aqui!!!

Sejá bem vindo, tenho certeza que as suas ideias irão contribuir muito para a comunidade .Net!

Abraços,


Victor Cavalcante



2010/7/28 felipe <feli...@gmail.com>

Vinicius Quaiato

unread,
Jul 28, 2010, 12:11:48 PM7/28/10
to dotnetar...@googlegroups.com
Puts Ricardo,
Ou eu não entendi nada do que vc falou, ou vc criou um monstro :P

Concordo com o que vc disse sobre a especialidade. Mas o que isso tem com o Builder? Um Buider cria objetos em partes, só isso.

Pelo que entendi do Tuca, não existem vários Geradores diferentes, o que muda é o Precificador que vai dentro do Gerador, este por sua vez que depende da Loja conhecida em runtime.

Sendo assim, não dá mesmo para usar um container para o precificador, e por isso sugeri uma estratégia baseada na Loja para conter o precificador.

felipe

unread,
Jul 28, 2010, 12:27:20 PM7/28/10
to .Net Architects
Quero só ver... :P

On Jul 28, 1:11 pm, Victor Cavalcante <vic...@cavalcante.net> wrote:
> Olhá quem está por aqui!!!
>
> Sejá bem vindo, tenho certeza que as suas ideias irão contribuir muito para
> a comunidade .Net!
>
> Abraços,
>
> Victor Cavalcante
>
> 2010/7/28 felipe <felip...@gmail.com>
> > dotnetarchitec...@googlegroups.com<dotnetarchitects%2Bunsubscrib e...@googlegroups.com>

Vinicius Quaiato

unread,
Jul 28, 2010, 12:39:09 PM7/28/10
to dotnetar...@googlegroups.com
Felipe, mesmo utilizando uma fábrica para o container criar a dependência, não teria que informar a tal da Loja?
2010/7/28 felipe <feli...@gmail.com>
--
Você recebeu esta mensagem porque faz parte do grupo .Net Architects hospedado no Google Groups.
Para postar envie uma mensagem para dotnetar...@googlegroups.com
Para sair do grupo envie uma mensagem para dotnetarchitec...@googlegroups.com

Vinicius Quaiato

unread,
Jul 28, 2010, 12:39:38 PM7/28/10
to dotnetar...@googlegroups.com
Ah sim, o Unity 2 suporta factories.
2010/7/28 felipe <feli...@gmail.com>
Fala moçada.

Ricardo Simões

unread,
Jul 28, 2010, 1:57:40 PM7/28/10
to dotnetar...@googlegroups.com
Oi,

Sobre o Builder,  para a solução em questão não vejo a necessidade de sua utilização. Só isso.

O que eu quis ilustrar foi o seguinte trecho de código.

//Trecho de código que você ilustrou
public void ExecutarTodoEsseProcesso(Loja lojaSelecionada)
{
   var precificadorEscolhido = AbstracaoDoContainer.CriarInstanciaDe<IPrecificador>(lojaSelecionada);

   var geradorDePedido = new GeradorDePedido(precificadorEscolhido);
   geradorDePedido.GerarNovo(pedido);
}

Aqui um trecho de código que o método GerarNovo poderia encapsular.

// Se desejar variar o algoritmo de geração de acordo com o tipo ou alguma outra informação do pedido de pedido.
var estrategia = FabricaDeEstrategias.Fabricar<IEstrategiaDeGeracaoDePedidos>(pedido);   

this.GerarNovoPedidoBaseadoEm(estrategia, precificador);

    
Aí está a minha idéia inicial.

[]'s

Ricardo Simões

Vinicius Quaiato

unread,
Jul 28, 2010, 2:22:17 PM7/28/10
to dotnetar...@googlegroups.com
Entendi.

É uma outra abordagem :P

tucaz

unread,
Jul 28, 2010, 2:39:21 PM7/28/10
to .Net Architects
As soluções do @Vinicius e do @Ricardo eu já havia chegado. O problema
é que no meu caso IPrecificador já é utilizado por diversos outros
objetos então vou ter que criar uma fabrica especifica pra criar cada
um desses objetos que usem IPrecificador. Além de ser utilizado em
diversos objetos, como uso container de DI as vezes ele é instanciado
em Nivel 2 do grafo de objetos, as vezes no Nivel 3.

@Felipe,

sua idéia é boa, mas onde vou passar a loja selecionada pra ser usada
na criação?

O método que vocês estão chamando de ExecutarTodoEsseProcesso é um
serviço WCF. Ele é o cara que usa o container de DI pra instanciar o
GeradorPedido e chamar os métodos que devem ser chamados.

On Jul 28, 3:22 pm, Vinicius Quaiato <vinicius.quai...@gmail.com>
wrote:
> Entendi.
>
> É uma outra abordagem :P
>
> *Vinicius Quaiato*http://viniciusquaiato.com
>
> Twitter <vquaiato>
> [image: Google Talk/]vinicius.quai...@gmail.com [image: MSN/]
> vinicius.quai...@gmail.com
>
> 2010/7/28 Ricardo Simões <rsc....@gmail.com>
>
>
>
> > Oi,
>
> > Sobre o Builder,  para a solução em questão não vejo a necessidade de sua
> > utilização. Só isso.
>
> > O que eu quis ilustrar foi o seguinte trecho de código.
>
> > //Trecho de código que você ilustrou
> > public void ExecutarTodoEsseProcesso(Loja lojaSelecionada)
> > {
> >    var precificadorEscolhido =
> > AbstracaoDoContainer.CriarInstanciaDe<IPrecificador>(lojaSelecionada);
>
> >    var geradorDePedido = new GeradorDePedido(precificadorEscolhido);
> >    geradorDePedido.GerarNovo(pedido);
> > }
>
> > Aqui um trecho de código que o método GerarNovo poderia encapsular.
>
> > // Se desejar variar o algoritmo de geração de acordo com o tipo ou alguma
> > outra informação do pedido de pedido.
> > var estrategia =
> > FabricaDeEstrategias.Fabricar<IEstrategiaDeGeracaoDePedidos>(pedido);
>
> > this.GerarNovoPedidoBaseadoEm(estrategia, precificador);
>
> > Aí está a minha idéia inicial.
>
> > []'s
>
> > Ricardo Simões
>
> > 2010/7/28 Vinicius Quaiato <vinicius.quai...@gmail.com>
>
> >> Puts Ricardo,
> >> Ou eu não entendi nada do que vc falou, ou vc criou um monstro :P
>
> >> Concordo com o que vc disse sobre a especialidade. Mas o que isso tem com
> >> o Builder? Um Buider cria objetos em partes, só isso.
>
> >> Pelo que entendi do Tuca, não existem vários Geradores diferentes, o que
> >> muda é o Precificador que vai dentro do Gerador, este por sua vez que
> >> depende da Loja conhecida em runtime.
>
> >> Sendo assim, não dá mesmo para usar um container para o precificador, e
> >> por isso sugeri uma estratégia baseada na Loja para conter o precificador.
>
> >> *Vinicius Quaiato*
> >>http://viniciusquaiato.com
>
> >> Twitter <http://vquaiato>
> >> [image: Google Talk/]vinicius.quai...@gmail.com [image: MSN/]
> >> vinicius.quai...@gmail.com
>
> >> 2010/7/28 Ricardo Simões <rsc....@gmail.com>
>
> >>> Oi, Vinicius,
>
> >>> Achei mesmo que tinha entendido seu conceito.
>
> >>> Contudo minha afirmação é realmente sobre o conceito da especialidade por
> >>> domínio. Não consigo imaginar um domínio que precise de mais de um
> >>> especialista na função de gerar pedidos.
>
> >>> Claro que o algoritmo de geração de pedido pode variar, como é o caso do
> >>> nosso amigo tuca, entretanto não é necessário solicitar isto para um outro
> >>> especialista na função, basta que ele saiba qual é o algoritmo de geração
> >>> que precisa utilizar e dar o resultado desejado.
>
> >>> Por este motivo acredito que um Strategy mesclado com FactoryMethod e
> >>> talvez um TemplateMethod resolva o problema.
>
> >>> Eu só iria considerar utilizar um container para os Precificadores, que
> >>> aí sim pode haver a necessidade de consultar mais que um neste domínio.
>
> >>> []'s
>
> >>> Ricardo Simões
>
> >>> 2010/7/28 Vinicius Quaiato <vinicius.quai...@gmail.com>
>
> >>>> Então ricardo, eu disse um Builder por que pelo que entendi mais de um
> >>>> lugar usa o Gerador, e o gerador depende de um IPrecificador, que por sua
> >>>> vez depende de uma loja.
>
> >>>> Para matar essa dependência com a loja, crio uma fábrica de
> >>>> EstratégiasDePrecificacao, e depois de obter passo a estratégia para o
> >>>> Gerador.
>
> >>>> Na verdade o Builder seria para ocultar os passos da criação do Gerador
> >>>> apenas.
>
> >>>> *Vinicius Quaiato*
> >>>>http://viniciusquaiato.com
>
> >>>> Twitter <http://vquaiato>
> >>>> [image: Google Talk/]vinicius.quai...@gmail.com [image: MSN/]
> >>>> vinicius.quai...@gmail.com
>
> >>>> 2010/7/28 Ricardo Simões <rsc....@gmail.com>
>
> >>>>> Oi,
>
> >>>>> Só não concordo com o Vinicius em ter que criar um Builder para isso,
> >>>>> uma fabrica de estratégias já seria suficiente para criar seu especialista
> >>>>> na precificação.
>
> >>>>> Além do mais não estou entendendo porque o GeradorDePedido precisa de
> >>>>> um container DI para ser criado.
>
> >>>>> Ele me parece ser um serviço especialista na função, e normalmente
> >>>>> teremos um único especialista na função por domínio.
>
> >>>>> Digo isso, porque imagino que no seu domínio você não precise de um
> >>>>> GeradorDePedidoDeCarros, GeradorDePedidosDeImoveis...
>
> >>>>> Ao que parece o container vai morrer mesmo...
>
> >>>>> []'s
>
> >>>>> Ricardo Simões
>
> >>>>> 2010/7/28 Vinicius Quaiato <vinicius.quai...@gmail.com>
>
> >>>>>> Não sei se precisa de uma AbstractFactory Tuca.
>
> >>>>>> Seu ponto é conseguir criar o GeradorDePedido, que agora depende de
> >>>>>> uma Loja que só é conhecida em runtime.
>
> >>>>>> Isso está mais para um Builder. E eu abriria mão do container nessa
> >>>>>> situação. O builder recebendo uma Loja cria o seu Gerador.
>
> >>>>>> Afinal o Gerado não muda por causa da loja, o que muda é o
> >>>>>> Precificador, por isso acho que não cabe uma abstract factory.
>
> >>>>>> E sobre a dependência de outro sobre IPrecificador, utilizaria uma
> >>>>>> fábrica para eles, baseado na loja. E essa fábrica será também consumida
> >>>>>> pelo Builder.
>
> >>>>>> Acho que o container vai dançar. Ou se alguém souber umas mágicas mais
> >>>>>> avançadas, manda aê.
>
> >>>>>>  *Vinicius Quaiato*
> >>>>>>http://viniciusquaiato.com
>
> >>>>>> Twitter <http://vquaiato>
> ...
>
> read more »

Vinicius Quaiato

unread,
Jul 28, 2010, 3:10:03 PM7/28/10
to dotnetar...@googlegroups.com
Tuca, quando você dá o Resolve no container, você pode passar parâmetros não pode?

(Qual container vc está usando?)
2010/7/28 tucaz <tuc...@gmail.com>
As soluções do @Vinicius e do @Ricardo eu já havia chegado. O problema

--

tucaz

unread,
Jul 28, 2010, 3:31:21 PM7/28/10
to .Net Architects
Ninject. Acredito que posso passar sim, mas só pra classe que estou
instanciando diretamente. Pras outras dependências dela acho que não
tem jeito. Pelo menos não consegui fazer.

On Jul 28, 4:10 pm, Vinicius Quaiato <vinicius.quai...@gmail.com>
wrote:
> Tuca, quando você dá o Resolve no container, você pode passar parâmetros não
> pode?
>
> (Qual container vc está usando?)
>
> ...
>
> read more »

felipe

unread,
Jul 28, 2010, 5:43:45 PM7/28/10
to .Net Architects
Pois é.. demorei pra responder, mas a idéia é que como vc vai passar
qual loje deve ser usada depende de quando vc recebe essa informação.

Você pode por exemplo passar no Resolve do container ou dar à Fabrica
conhecimento para descobrir isso sozinha em tempo de execução.
Você armazena essa informação em algum lugar?

Outra opção é coloca um método de interceptação. Algo como AOP ou
Before Initialize ou After Initialize. No Spring eu sei que tem.

[]'s

Felipe
> ...
>
> read more »

Thiago Alves

unread,
Jul 28, 2010, 6:10:17 PM7/28/10
to dotnetar...@googlegroups.com
Vejamos se entendi bem seu problema:

No seu serviço WCF você tem uma instância de Pedido (com uma lista de Item) e uma instância de Loja, e quer obter um GeradorDePedido, que por sua vez recebe uma instância específica de objeto que implementa a interface IPrecificador.

Talvez o esquema seja fazer isso em duas etapas. Que tal esta solução?

var pedido = pedidoRepository.Get(1);
var loja = lojaRepository.Get(1);

var precificador = container.Resolve<IPrecificador>(loja);
var gerador = new GeradorDePedido(precificador);

gerador.GerarPedido(pedido);

Abraço!

2010/7/28 tucaz <tuc...@gmail.com>

--

tucaz

unread,
Jul 29, 2010, 7:29:58 AM7/29/10
to .Net Architects
Thiago,

isto é o que eu estou utilizando agora, mas não está legal ainda, pois
além do GeradorPedido outros objetos utilizam IPrecificador e, como eu
falei anteriormente, em um segundo ou terceiro nivel de indireção.

No meu exemplo acima IPrecificador está no primeiro nivel
(GeradorPedido -> IPrecificador), mas pode acontecer de ele estar em
um nível mais abaixo (GeradorPedido -> CalculadoraFrete ->
IPrecificador) ai var precificador =
container.Resolve<IPrecificador>(loja); não funciona a não ser que eu
contrua o grafo todo de dependências manualmente.

On Jul 28, 7:10 pm, Thiago Alves <thiago1...@gmail.com> wrote:
> Vejamos se entendi bem seu problema:
>
> No seu serviço WCF você tem uma instância de Pedido (com uma lista de Item)
> e uma instância de Loja, e quer obter um GeradorDePedido, que por sua vez
> recebe uma instância específica de objeto que implementa a interface
> IPrecificador.
>
> Talvez o esquema seja fazer isso em duas etapas. Que tal esta solução?
>
> var pedido = pedidoRepository.Get(1);
> var loja = lojaRepository.Get(1);
>
> var precificador = container.Resolve<IPrecificador>(loja);
> var gerador = new GeradorDePedido(precificador);
>
> gerador.GerarPedido(pedido);
>
> Abraço!
>
> 2010/7/28 tucaz <tuca...@gmail.com>
> ...
>
> read more »

Pedro Reys

unread,
Jul 29, 2010, 9:58:39 AM7/29/10
to dotnetar...@googlegroups.com
Tuca,

Não conheço o Ninject, mas no StructureMap você pode usar uma feature normalmente utilizada para automação de testes para resolver esse seu problema.

No StructureMap eu posso injetar no container um objeto que eu quero que seja retornado como o objeto padrão para um certo tipo. Normalmente isso é feito para injetoar um mock/stub no container.

No seu caso creio que dava para utilizar essa feature para injetar a especificação de IPrecificador que você quer que seja usada.

Ficaria algo mais ou menos assim:

//No lugar onde você sabe qual a loja

IPrecificador precificador = FabricaDePrecificador.RetornaPrecificadorPara(loja);

// A instância do precificador para a loja é injetada no container.
ObjectFactory.Inject(precificador);

Com isso, sempre que o container precisar de um IPrecificador a partir de agora, ele vai utilizar a instância que foi injetada, com isso você pode fazer o ServiceLocation normalmente, sem precisar construir o grafo na mão.


- Pedro Reys



2010/7/29 tucaz <tuc...@gmail.com>
> ...
>
> read more »

tucaz

unread,
Jul 29, 2010, 10:05:12 AM7/29/10
to .Net Architects
@PedroReys

That´s my boy!

Tai uma solução que eu gostei. Deixa eu ver como fazer isso no
Ninject! :)

Thanks!

On Jul 29, 10:58 am, Pedro Reys <pedror...@gmail.com> wrote:
> Tuca,
>
> Não conheço o Ninject, mas no StructureMap você pode usar uma feature
> normalmente utilizada para automação de testes para resolver esse seu
> problema.
>
> No StructureMap eu posso injetar no container um objeto que eu quero que
> seja retornado como o objeto padrão para um certo tipo. Normalmente isso é
> feito para injetoar um mock/stub no container.
>
> No seu caso creio que dava para utilizar essa feature para injetar a
> especificação de IPrecificador que você quer que seja usada.
>
> Ficaria algo mais ou menos assim:
>
> //No lugar onde você sabe qual a loja
>
> IPrecificador precificador =
> FabricaDePrecificador.RetornaPrecificadorPara(loja);
>
> // A instância do precificador para a loja é injetada no container.
> ObjectFactory.Inject(precificador);
>
> Com isso, sempre que o container precisar de um IPrecificador a partir de
> agora, ele vai utilizar a instância que foi injetada, com isso você pode
> fazer o ServiceLocation normalmente, sem precisar construir o grafo na mão.
>
> - Pedro Reys
>
> 2010/7/29 tucaz <tuca...@gmail.com>
> ...
>
> read more »

Pedro Reys

unread,
Jul 29, 2010, 2:12:53 PM7/29/10
to dotnetar...@googlegroups.com
Tuca,

Vendo agora, o SM tem uma outra maneira de fazer isso, ate melhor IMO.

Na  hora de pedir pelo gerador voce diz qual instancia eh para ele usar para o IPrecificador

var gerador = ObjectFacotry.With(precificador).GetInstance<IGeradorDePedidos>();

Dessa maneira ele usa a instancia que vc passou para resolver as dependencias do GeradorDePedidos, sem deixar efeitos colaterais.

- Pedro Reys



2010/7/29 tucaz <tuc...@gmail.com>
> ...
>
> read more »

tucaz

unread,
Jul 29, 2010, 2:33:26 PM7/29/10
to .Net Architects
Uia...procurei hoje de manha alguma maneira de fazer isso com Ninject,
mas não achei. Se eu não achar vou mudar pro StructureMap.

On Jul 29, 3:12 pm, Pedro Reys <pedror...@gmail.com> wrote:
> Tuca,
>
> Vendo agora, o SM tem uma outra maneira de fazer isso, ate melhor IMO.
>
> Na  hora de pedir pelo gerador voce diz qual instancia eh para ele usar para
> o IPrecificador
>
> var gerador =
> ObjectFacotry.With(precificador).GetInstance<IGeradorDePedidos>();
>
> Dessa maneira ele usa a instancia que vc passou para resolver as
> dependencias do GeradorDePedidos, sem deixar efeitos colaterais.
>
> - Pedro Reys
>
> 2010/7/29 tucaz <tuca...@gmail.com>
> ...
>
> read more »

Paulo Roberto Pellucci

unread,
Jul 29, 2010, 3:17:16 PM7/29/10
to dotnetar...@googlegroups.com
E pra quem fala que nunca viu ninguém trocar de framework para DI/IoC, taí o primeiro caso do grupo, rs..

2010/7/29 tucaz <tuc...@gmail.com>
> ...
>
> read more »

--
Você recebeu esta mensagem porque faz parte do grupo .Net Architects hospedado no Google Groups.
Para postar envie uma mensagem para dotnetar...@googlegroups.com
Para sair do grupo envie uma mensagem para dotnetarchitec...@googlegroups.com
Para mais opções visite o grupo em http://groups.google.com/group/dotnetarchitects?hl=pt-br



--
Atenciosamente,
Paulo Roberto S. Pellucci

Bruno D'Alessio

unread,
Jul 29, 2010, 3:27:25 PM7/29/10
to dotnetar...@googlegroups.com
Verdade,
aguardando cenas do próximo capitulo!

Bruno D'Alessio
Arquiteto de Software

Vinicius Quaiato

unread,
Jul 29, 2010, 6:17:33 PM7/29/10
to dotnetar...@googlegroups.com
Tuca, mas essa escolha da loja é tão "global" assim no lifecycle dos seus objetos? 

Digo, uma vez que se sabe a loja, você diz que o IPrecificador é sempre aquele a ponto de poder usar esse cara sempre que for preciso?
Parece estranho. Mas, se é assim, é fácil mesmo.

Abraços,
2010/7/29 tucaz <tuc...@gmail.com>
> ...
>
> read more »

tucaz

unread,
Jul 29, 2010, 6:58:29 PM7/29/10
to .Net Architects
É sim Vinicius. Pelo menos para Request em questão é sim. Durante toda
a request não preciso trocar a loja.

Pesquisei e vi que o Ninject não permite fazer isso que o Pedro falou
de maneira nativa. Só com uma "gambiarra". Já testei aqui com o
StructureMap e funcionou bonitinho. Parece que vou mesmo trocar de
container de IoC/DI.

On Jul 29, 7:17 pm, Vinicius Quaiato <vinicius.quai...@gmail.com>
wrote:
> Tuca, mas essa escolha da loja é tão "global" assim no lifecycle dos seus
> objetos?
>
> Digo, uma vez que se sabe a loja, você diz que o IPrecificador é sempre
> aquele a ponto de poder usar esse cara sempre que for preciso?
> Parece estranho. Mas, se é assim, é fácil mesmo.
>
> Abraços,
>
> *Vinicius Quaiato*http://viniciusquaiato.com
>
> Twitter <vquaiato>
> [image: Google Talk/]vinicius.quai...@gmail.com [image: MSN/]
> vinicius.quai...@gmail.com
>
> 2010/7/29 tucaz <tuca...@gmail.com>
> ...
>
> read more »

Juliano Oliveira

unread,
Jul 29, 2010, 7:30:14 PM7/29/10
to dotnetar...@googlegroups.com
O primeiro framework de IoC que usei foi StructureMap. Tinha até feito um posto no meu blog na época.
Quem usava (ou usa ainda, não sei) era o Rob Conery

[]´s

Juliano Oliveira
Analista Desenvolvedor
twitter: @juloliveira - skype: juloliveira


> ...
>
> read more »

Vanderlei Pereira

unread,
Jul 30, 2010, 2:15:06 PM7/30/10
to dotnetar...@googlegroups.com
@Paulo, 

Eu estava participando da outra thread aqui mesmo falando justamente na necessidade de usar um pattern facade para o framework de IOC pensando justamente no baixo acoplamento por meio de abstração e a facilidade em que o arquiteto terá quando for necessário trocá-lo.
 
@Tucaz você encontrou uma maneira de manter o Ninject para resolver essa necessidade ou trocou para StructureMap?


[ ]´s

Vanderlei Pereira
Software Architect at Telephone.com  - http://www.telephone.com   


tucaz

unread,
Jul 30, 2010, 2:35:59 PM7/30/10
to .Net Architects
@Vanderlei,

eu usava o Ninject 1.5. Fiz o upgrade pra 2.0 que oferece um método
parecido (Rebind), mas que troca o bind globalmente pra um determinado
tipo. E "rebind" não é o que eu queria. Eu precisava que pra um
Resolve especifico ele usasse uma instância que eu determinasse. Não
achei como fazer (acredito que não tem jeito) então mudei pra
StructureMap. Fácil, fácil!

On Jul 30, 3:15 pm, Vanderlei Pereira <vanderleiperei...@gmail.com>
wrote:

Paulo Roberto Pellucci

unread,
Jul 30, 2010, 2:37:14 PM7/30/10
to dotnetar...@googlegroups.com
Vanderlei, foi exatamente por isto que eu postei isto, rs.
 
Rolou quase ao mesmo tempo a discussão de uma façade para facilitar a troca do framework de IoC e uma das coisas que levantaram por lá é que raramente acontece esta troca, no entanto, acabamos de ver acontecer.
 
Tuca, vocês tinham esse façade no projeto? Como foi o "re-trabalho" desta troca?
2010/7/30 tucaz <tuc...@gmail.com>
--
Você recebeu esta mensagem porque faz parte do grupo .Net Architects hospedado no Google Groups.
Para postar envie uma mensagem para dotnetar...@googlegroups.com
Para sair do grupo envie uma mensagem para dotnetarchitec...@googlegroups.com
Para mais opções visite o grupo em http://groups.google.com/group/dotnetarchitects?hl=pt-br
Reply all
Reply to author
Forward
0 new messages