Pergunta

Na maioria das amostras que tenho visto na web, DI em controladores de MVC é feito assim

public ProductController(IProductRepository Rep)
{
    this._rep = Rep;
}

A ControllerFactory personalizado é usado e ele utiliza a estrutura DI de escolha e o repositório é injetado.

Por que o acima considerado melhor do que

public ProuctController()
{
    this._rep = ObjectFactory.GetInstance<IProductRepository>();
}

Isto irá obter os mesmos resultados, mas não exige uma fábrica de controlador personalizado.

Tanto quanto o teste está em causa o Test App pode ter um BootStrapper separado. Dessa forma, quando os controladores estão sendo testados eles podem obter os repositórios falsos e quando eles são utilizados para real que irão receber os reais.

Foi útil?

Solução

Construtor de injeção (a primeira abordagem) é melhor do que o padrão de localizador de serviço (a segunda abordagem) por várias razões.

dependências

Em primeiro lugar, serviço de localizador de peles. Em seu segundo exemplo, olhando para a interface pública por si só, não há nenhuma maneira de saber que os repositórios de necessidade ProductControllers.

Além do mais, eu tenho que echo OdeToCode . Acho

IProductRepository repository = Mockery.NewMock<IProductRepository>();
IProductController controller = new ProductController(repository);

é mais clara do que

ObjectFactory.SetFactory(IProductRepository, new MockRepositoryFactory())
IProductController controller = new ProductController();

Especialmente se o ObjectFactory é configurado em forma de SetUp de um suporte de ensaio.

Finalmente, o padrão de localizador de serviço é comprovadamente sub-óptima em pelo menos um caso particular: quando você está escrevendo código que será consumido por pessoas que escrevem aplicações fora do seu controle. aposta I que as pessoas geralmente preferem injeção de construtor (ou um dos outros métodos DI) porque é aplicável para todos os cenários. Por que não usar o método que abrange todos os casos?

(Martin Fowler oferece uma análise muito mais profunda na "Inversão de Controle Containers e o padrão Dependency Injection" , especialmente a seção "Service Locator vs Dependency Injection").

Outras dicas

A principal desvantagem para o segundo construtor é agora seu contêiner IoC tem de ser devidamente configurado para cada teste. Esta configuração pode se tornar um fardo real como a base de código cresce e os cenários de teste tornam-se mais variada. Os testes são geralmente mais fáceis de ler e manter quando você explicitamente passar em um teste duplo.

Outra preocupação é o acoplamento de um grande número de classes para um quadro específico DI / IOC. Existem maneiras para abstrair-lo fora, é claro, mas você ainda tem código cheio durante todo suas classes para recuperar dependências. Uma vez que todos os quadros bons pode descobrir que dependências que você precisa de olhar para o construtor, é um monte de desperdício de esforços e código duplicado.

Quando você usa a segunda abordagem, as desvantagens são:

  • métodos setup / contexto de teste enorme e ilegível são necessários
  • O recipiente é acoplado ao controlador
  • Você precisa escrever muito mais código

Por que você quer usar um recipiente COI qualquer maneira, quando você não quer que a injeção de dependência?

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