Pergunta

Eu tenho um objeto que implementa IDisposable que está registrado com o Windsor Container e eu gostaria de eliminá-lo por isso é Dispose método é chamado e próxima Resolve tempo é chamado ele busca uma nova instância.

O

container.Release(obj); 

automaticamente chamar Dispose () imediatamente? Ou eu preciso fazer

obj.Dispose();
container.Release(obj);

Não foi possível encontrar nada na documentação sobre o que exatamente lançamento faz

EDIT: Veja minha resposta abaixo os resultados de testes que fiz. Agora, a questão torna-se, como faço para forçar o recipiente para liberar uma instância de um componente com um ciclo de vida singleton? Isso só precisa ser feito em um lugar e escrever um ciclo de vida personalizado parece muito pesado, é que não há construído em forma de fazê-lo?

Foi útil?

Solução

Este é algo que eu acho que as pessoas não estão realmente cientes de quando se trabalha com o recipiente de Windsor - especialmente a freqüência surpreendendo comportamento que componentes transitórios descartáveis ??são realizadas em pelo recipiente para a vida do kernel até que ele está disposto a menos que você liberá-los a si mesmo - embora seja documentado - dê uma olhada aqui - mas para citar rapidamente:

o MicroKernel tem uma política de liberação conectável que pode ligar e implementar algumas encaminhamento para eliminar os componentes. O MicroKernel vem com implementações de três IReleasePolicy:

  • AllComponentsReleasePolicy: rastrear todos os componentes para impor a eliminação correcta quando da alienação exemplo MicroKernel
  • LifecycledComponentsReleasePolicy: somente rastrear componentes que têm um ciclo de vida decommission associado
  • NoTrackingReleasePolicy: não executa qualquer acompanhamento

Você também pode implementar sua própria política de liberação usando a IReleasePolicy interface.

O que você pode achar mais fácil é mudar a política a um NoTrackingReleasePolicy e, em seguida, lidar com a eliminação si mesmo - este é potencialmente arriscado, bem como, mas se os seus estilos de vida são em grande parte transitório (ou se quando o recipiente está disposto a sua aplicação está prestes a fechar de qualquer maneira) provavelmente não é um grande negócio. Lembre-se, porém, que todos os componentes que já foram injetados com o singleton irá realizar uma referência, então você pode acabar causando problemas ao tentar "refresh" seus singletons - parece uma má prática, e me pergunto se talvez você pode evitar ter que fazer isso em primeiro lugar, melhorando a maneira como os aplicativos juntos.

Outras abordagens são para construir um ciclo de vida personalizado com a sua implementação própria decommission (assim liberando o Singleton seria realmente descarte do componente, bem como o ciclo de vida transitória faz).

Como alternativa outra abordagem é ter um decorador para o seu serviço registrado no recipiente com um estilo de vida Singleton, mas o seu serviço subjacente real registrado no recipiente com um estilo de vida transitória - então quando você precisa atualizar o componente apenas dispor do transiente subjacente componente realizada pelo decorador e substituí-la por uma instância recém-resolvido (resolvê-lo usando a chave componentes, em vez do serviço, para evitar o decorador) - isso evita problemas com outros serviços únicos (que não estão sendo "refrescado" ) de agarrar serviços obsoletos que foram eliminados tornando-as inutilizáveis, mas requer um pouco de vazamento etc, para fazê-lo funcionar.

Outras dicas

Depende do estilo de vida do componente que você especificou quando você adicionou-lo ao recipiente.

Você usaria Release () Se o estilo de vida é agrupada. Isso coloca a parte de trás do componente na piscina para a próxima recuperação (o objeto não é destruído, então a eliminação seria ruim)

Se o estilo de vida é transitória, um novo objeto é criado quando você recebe o componente. Neste caso, a disposição é com você, e você não precisa chamar Release

Se o estilo de vida é Thread, o mesmo componente é usado para cada segmento, não destruído.

Se o estilo de vida é Singleton, apenas um componente é criado e não detroyed.

O mais provável é que você está usando componentes transitórios? (Se você estiver preocupado com a eliminá-los em tempo hábil) nesse caso, apenas envolvê-lo com um usando e você está pronto (ou chamar a dispor-se em algum lugar)

using(ISomeService service = container.Resolve<ISomeService>())
{
 // Do stuff here
 // service.Dispose is automatically called 
}

Editar - Sim, a fim de "refresh" ou descarte e recriar o seu singleton você precisa se quer destruir o recipiente ou escrever um ciclo de vida personalizado. Fazendo um ciclo de vida personalizado não é realmente tão difícil e mantém a lógica para fazer isso em um só lugar.

Tudo bem, então eu tenho a execução de testes e parece que Container.Release() vai causar implicitamente método Dispose() de um IDisposable para executar somente se o estilo de vida é transitória (este é provavelmente não é exatamente correta, mas o ponto é que ele não vai' fazer uma coisa darn se o estilo de vida é singleton).

Agora, se você chamar Container.Dispose() ele irá chamar os métodos descartáveis ??também, embora, infelizmente, vai dispor de todo o kernel e você terá que adicionar todos os componentes de volta em:

var container = new WindsorContainer();
container.AddComponentWithLifestyle<MyDisposable>(Castle.Core.LifestyleType.Singleton);
var obj = container.Resolve<MyDisposable>();  // Create a new instance of MyDisposable
obj.DoSomething();
var obj2 = container.Resolve<MyDisposable>();  // Returns the same instance as obj
obj2.DoSomething();
container.Dispose();  // Will call the Disposable method of obj
// Now the components need to be added back in   
 container.AddComponentWithLifestyle<MyDisposable>(Castle.Core.LifestyleType.Singleton);
var obj3 = container.Resolve<MyDisposable>();  // Create a new instance of MyDisposable

Felizmente no meu caso eu posso dar ao luxo de simplesmente colocar todos os componentes e posso restaurá-los facilmente. No entanto, este é sub-óptima.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top