¿Quién debe inicializar las dependencias en una aplicación TDD?

8

Estoy tratando de aprender a implementar TDD con burlas / objetos falsos. Una de las preguntas que tengo es cómo inicializar una dependencia en una aplicación que implementa TDD. Un ejemplo de este artículo Beginning Mocking With Moq 3 muestra:

public class OrderWriter
{
    private readonly IFileWriter fileWriter;

    public OrderWriter(IFileWriter fileWriter)
    {
        this.fileWriter = fileWriter;
    }

    public void WriteOrder(Order order)
    {
        fileWriter.WriteLine(String.Format("{0},{1}", order.OrderId, order.OrderTotal));
    }
}

En este ejemplo, el constructor toma un IFileWriterparámetro, supongo que porque desea proporcionar el escritor de archivo real en el caso de la aplicación real, y el falso para la prueba unitaria. Mi pregunta es, en la aplicación real, ¿quién proporcionará este parámetro? Supongo que será la persona que llama de esta aplicación. ¿Qué pasa si también tiene dependencia en el constructor? ¿El código de la persona que llama también será responsable de eso?

Quizás la mejor manera es usar la fábrica. ¿Cómo funcionaría esta fábrica? ¿Y cómo se distribuirá la fábrica? ¿Estará en el parámetro constructor como en la forma anterior?

Louis Rhys
fuente

Respuestas:

7

Lo que está buscando es un contenedor de IoC para conectar automáticamente todos sus objetos al inicio de la aplicación. Eche un vistazo a Ninject , tiene un ejemplo muy simple en la portada. (También es un buen producto y ... bueno, ¡ninjas!)

Como regla general, debe intentar resolver todos sus objetos de nivel superior (por ejemplo, Página en ASP.NET, Controlador en MVC para ASP.NET, Formulario en Winforms) directamente desde el contenedor de IoC y dejar que conecte TODOS sus dependencias a través de la inyección del constructor. Habrá momentos en los que tendrá que obligarlo a resolver un elemento de nivel inferior, esto se conoce como usarlo como un Localizador de servicios , pero esto generalmente debe evitarse ya que son difíciles (pero no imposibles) de probar, y cree una API que pueda ser confusa para el consumidor, si ese no es usted.

ASP.NET para MVC, desde v3, ha sido diseñado específicamente para abstraer el contenedor de IoC del resto de su código mientras le permite inyectarse automáticamente en cualquier clase de nivel superior (Controlador, Vista, Filtro, etc.) a través de DependencyResolver clase . Otros marcos .NET requieren un poco más de esfuerzo, pero es posible si buscas en Google.

Hay un libro sobre el tema llamado Inyección de dependencias en .NET . No lo he leído personalmente, pero he escuchado cosas buenas.

pdr
fuente
0

He visto el enfoque de agregar un constructor predeterminado que llama al constructor parametrizado con instancias predeterminadas, es decir, "inyección de dependencia del pobre".

public OrderWriter()
    : this(new TextFileWriter())
{
}

La ruta de código regular llama al constructor predeterminado, mientras que la prueba unitaria se inicializa utilizando el constructor personalizado.

Si alguien pudiera explicar los pros y los contras de este enfoque, lo agradecería mucho.

Timo
fuente