2010-06-17 18 views
5

Estoy tratando de comenzar con una inyección de dependencia simple usando C# y me he encontrado con un problema que parece que no me ha dado una respuesta.Inyección de dependencia C#: cómo inyectar una dependencia sin fuente?

Tengo una clase escrita por otro departamento para la que no tengo la fuente en mi proyecto. Quería inyectar un objeto de este tipo a través de un constructor utilizando una interfaz, pero, por supuesto, no puedo cambiar la implementación de los objetos inyectados para implementar la interfaz para lograr el polimorfismo al convertir el objeto al tipo de interfaz.

Cada ejemplo académico que he visto de esta técnica tiene las clases utiliza clases que se declaran en el proyecto en sí. ¿Cómo podría inyectar mi dependencia sin que la fuente esté disponible en el proyecto?

Espero que tenga sentido, gracias.

Respuesta

0

Si no tiene la necesidad de cambiar nada en una clase, apenas necesita el código. Supongamos que tiene una clase X en una DLL que desea inyectar a otra clase Y que está escribiendo. En tal caso, puede crear una instancia de X y poner como parámetro en el constructor de Y. Esto se verá más o menos así:

Agregue una referencia a la DLL que contiene la clase X en su proyecto.

Use NameSpaceOfX; 
Class Y 
{ 
    Public Y() //Default constructor 
    { 
    } 

    Public Y(X instanceOfX) 
    { 
     //Use instanceOfX here as required 
    } 
} 

En su código principal:

//Create instance of X 
X instanceOfX = new X(); 
//Inject it into Y 
Y instanceOfY = new Y(instanceOfX); 
//Use Y now. 
6

Se puede crear una envoltura alrededor de su tipo de destino, así que por ejemplo, usted podría tener una clase que proporcione:

public class TheirClass 
{ 
    public void DoSomething(); 
} 

Con qué puede definir una interfaz:

public interface ITheirClass 
{ 
    void DoSomething(); 
} 

y poner en práctica esa interfaz en una clase de contenedor:

public class TheirClassWrapper : TheirClass, ITheirClass 
{ 

} 

O, si la clase que siempre está sellada, es necesario hacerlo de forma ligeramente diferente:

public class TheirClassWrapper : ITheirClass 
{ 
    private TheirClass instance = new TheirClass(); 

    public void DoSomething() 
    { 
    instance.DoSomething(); 
    } 
} 

A continuación, se puede inyectar esa interfaz en su lugar.

Sé en MEF que podemos exportar tipos de concreto y hacer que se inyecten correctamente, pero no estoy seguro acerca de otros contenedores de IoC.

+0

Esto era exactamente lo que estaba pensando. – Steven

+0

Patrón de adaptador. Buena llamada. – Wix

1

La pregunta es, ¿por qué quieres inyectarla como interfaz? ¿Es porque la clase implementa algunas propiedades/métodos que le gustaría abstraer para que pueda ser sustituido, o simplemente está tratando de "forzar" una interfaz de marcador porque "siempre dependemos de interfaces, no de clases concretas"? ? Si es el último, entonces estás en el camino equivocado, ya que es probable que simplemente lo arrojes al concreto de inmediato de todos modos.

Suponiendo que el primero de los dos Veo dos opciones:

  1. utilizar la herencia en su lugar. Esto puede o no ser posible dependiendo de la clase que se haya creado, pero podría heredar de ella y sustituir su nueva clase por la anterior.
  2. Cree usted mismo la interfaz, con los métodos/propiedades que necesita y ajuste la clase concreta externa en una clase que implemente la interfaz.

Para la opción 2, si no se puede heredar, como un ejemplo, suponiendo que sólo se preocupan por un método en la clase (lo llamaremos Método1()) se crea una interfaz de juego para él:

public interface IMyNewInterface 
{ 
    void Method1(); 
} 

a continuación, cree una implementación de la misma que tiene la clase concreta como una dependencia (inyectado por su contenedor de forma normal) que sólo llama a la clase concreta:

public class MyNewClass : IMyNewInterface 
{ 
    private MyConcreteClass _MyConcreteClass; 

    public void MyNewClass(MyConcreteClass concreteClass) 
    { 
     _MyConcreteClass = concreteClass; 
    } 

    public void Method1() 
    { 
     _MyConcreteClass.Method1(); 
    } 
} 
+0

Pero con la última de las dos opciones, sería posible probar la unidad de su propia clase que utiliza la clase de terceros como un argumento pasado al constructor. es decir, sería posible burlarse de TheirClass con ITheirClass –

+0

Ambas opciones le permiten sustituir su clase (aparte de los genéricos), sin embargo, el enfoque de la interfaz sería mi preferencia. –

+0

Lo siento, no quise decir las opciones 1 y 2. Se refería a la frase "... siempre dependemos ...". Quizás leí mal Quizás quisiste decir que no debería hacerse solo por el bien de hacerlo. Pero las buenas prácticas significan que facilitamos el camino para futuros cambios o mantenimiento. Si la clase fue inyectada, entonces sería más fácil inyectarla con, por ejemplo, medición de rendimiento. –

Cuestiones relacionadas