Pergunta

Geralmente, eu gosto de manter uma aplicação completamente ignorante do contêiner IoC. No entanto eu tenho teve problemas onde eu necessários para acessá-lo. Abstrair a dor que eu usar um Singleton básico. Antes de correr para as montanhas ou puxe a espingarda, que me deixes passar a minha solução. Basicamente, o singleton IoC faz absolutamente nada, ele simplesmente delega para uma interface interna que deve ser passado. Eu descobri isso faz com que trabalham com o Singleton menos doloroso.

Abaixo está o invólucro IoC:

public static class IoC
    {
        private static IDependencyResolver inner;

        public static void InitWith(IDependencyResolver container)
        {
            inner = container;
        }

        /// <exception cref="InvalidOperationException">Container has not been initialized.   Please supply an instance if IWindsorContainer.</exception>
        public static T Resolve<T>()
        {
            if ( inner == null)
                throw new InvalidOperationException("Container has not been initialized.  Please supply an instance if IWindsorContainer.");

            return inner.Resolve<T>();
        }

        public static T[] ResolveAll<T>()
        {
            return inner.ResolveAll<T>();
        }
    }

IDependencyResolver:

public interface IDependencyResolver
    {
        T Resolve<T>();
        T[] ResolveAll<T>();
    }

Eu tive grande sucesso até agora com as poucas vezes que eu usei-o (talvez uma vez a cada poucos projetos, eu realmente prefiro não ter que usar isso em todos), como eu pode injetar qualquer coisa que eu quero: Castle, um Stub , falsificações, etc.

Esta é uma estrada escorregadia? Eu vou correr para possíveis problemas na estrada?

Foi útil?

Solução

Eu vi que mesmo implementos Ayende esse padrão no código Rhino Commons, mas eu aconselho a usá-lo sempre que possível. Há uma razão para que o Castelo de Windsor não tem este código por padrão. StructureMap faz, mas Jeremy Miller foi se afastando dele. Idealmente, você deve considerar o próprio recipiente com tanta desconfiança, como qualquer variável global.

No entanto, como uma alternativa, você pode sempre configurar o seu recipiente para IDependencyResolver determinação como uma referência para o seu recipiente. Isso pode parecer loucura, mas é significativamente mais flexível. Basta lembrar a regra de ouro que um objeto deve chamar "novo" ou executar o processamento, mas não ambos. Para "chamada nova" substituir por "resolver uma referência".

Outras dicas

Isso não é realmente uma classe Singleton. Isso é uma classe estática com membros estáticos. E sim que parece ser uma abordagem bem.

Eu acho JP Boodhoo tem até um nome para este padrão. O estática gateway padrão .

Apenas uma nota: padrões e práticas da Microsoft criou um localizador de serviço comum ( http: //www.codeplex. com / CommonServiceLocator ) que a maioria dos grandes recipientes de IoC será implementar no futuro próximo. Você pode começar a usá-lo em vez de seu IDependencyResolver.

BTW:. Esta é a maneira comum de resolver o seu problema e ele funciona muito bem

Tudo depende da utilização. Usando o recipiente assim é chamado o padrão Service Locator. Há casos em que não é um bom ajuste e casos em que se aplicam.

Se você google "padrão de localizador de serviço", você verá um monte de posts dizendo que é um anti-padrão, o que não é. O padrão foi simplesmente demasia (/ abusado).

Para a linha típica de aplicações de negócio você não deve usar SL como você esconder as dependências. Você também tem um outro problema: você não pode gerenciar o estado / vida se você usar o container raiz (em vez de uma de suas vidas)

.

Serviço localizador é uma boa opção quando se trata de infra-estrutura. Por exemplo ASP.NET MVC usa Service Locator para ser capaz de resolver todas as dependências para cada controlador.

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