Injeção de dependência com Ninject, MVC 3 e usando o padrão do localizador de serviço

Algo que está me incomodando desde que li uma resposta em outra pergunta sobre o stackoverflow (a exata me escapa agora) em que um usuário declarou algo como "Se você está ligando para o Localizador de serviços, está fazendo algo errado."

Era alguém com uma reputação alta (nas centenas de milhares, eu acho), por isso acho que essa pessoa pode saber do que está falando. Eu tenho usado o DI para meus projetos desde que comecei a aprender sobre ele e como ele se relaciona com o Teste de Unidade e o que não. É algo com o qual estou bastante confortável agora e eupensar Eu sei o que estou fazendo.

No entanto, há muitos lugares em que tenho usado o Localizador de Serviços para resolver dependências no meu projeto. Uma vez que o exemplo principal vem de minhas implementações do ModelBinder.

Exemplo de um fichário de modelo típico.

public class FileModelBinder : IModelBinder {
    public object BindModel(ControllerContext controllerContext,
                            ModelBindingContext bindingContext) {
        ValueProviderResult value = bindingContext.ValueProvider.GetValue("id");

        IDataContext db = Services.Current.GetService<IDataContext>();
        return db.Files.SingleOrDefault(i => i.Id == id.AttemptedValue);
    }
}

não é uma implementação real - apenas um exemplo rápido

Como a implementação do ModelBinder requer uma nova instância quando um Binder éprimeiro solicitado, é impossível usar a Injeção de Dependência no construtor para esta implementação específica.

É assim em muitas das minhas aulas. Outro exemplo é o de um processo de Expiração de cache que executa um método sempre que um objeto de cache expira no meu site. Eu corro um monte de chamadas de banco de dados e quais não. Também estou usando um localizador de serviço para obter a dependência necessária.

Outro problema que tive recentemente (sobre o qual postei uma pergunta aqui) foi que todos os meus controladores exigiram uma instância do IDataContext que eu usei DI - mas1 O método de ação requeria uma instância diferente do IDataContext. Felizmente Ninject veio ao resgate com uma dependência nomeada. No entanto, isso parecia um clamor e não uma solução real.

Eu pensei que, pelo menos, entendesse razoavelmente bem o conceito de Separação de Preocupações, mas parece haver algo fundamentalmente errado em como eu entendo a Injeção de Dependência e o Padrão do Localizador de Serviço - e não sei o que é isso.

A maneira que eu entendo atualmente - e isso também pode estar errado - é que, pelo menos no MVC, o ControllerFactory procura um construtor para um controlador e chama o localizador de serviço para obter as dependências necessárias e depois transferi-las. , Eu posso entender que nem todas as classes e o que não tem uma fábrica para criá-las. Portanto, parece-me que algum padrão do Localizador de Serviço é aceitável ... mas ...

Quando não é aceitável?Que tipo de padrão devo procurar quando repensar como estou usando o Service Locator Pattern?Minha implementação do ModelBinder está errada? Se sim, o que preciso aprender para corrigi-lo?Em outra pergunta, na linha deste usuárioMark Seemann recomendou uma fábrica abstrata - como isso se relaciona?

Eu acho que é isso - eu realmente não consigo pensar em nenhuma outra pergunta para ajudar minha compreensão, mas qualquer informação extra é muito apreciada.

Entendo que o DI pode não ser a resposta para tudo e posso estar exagerando na maneira como o implemento, no entanto, parece funcionar da maneira que eu esperava com o Teste de Unidade e o que não.

Não estou procurando código para corrigir meu exemplo de implementação - estou procurando aprender, procurando uma explicação para corrigir meu entendimento defeituoso.

Eu gostaria que o stackoverflow.com tivesse a capacidade de salvar rascunhos de perguntas. Também espero que quem quer que responda a essa pergunta obtenha a quantidade adequada de reputação para responder a essa pergunta, pois acho que estou pedindo muito. Desde já, obrigado.

questionAnswers(1)

yourAnswerToTheQuestion