2010-09-04 8 views
9
public interface ITaskProvider 
{ 
    T GetTask<T>(); 
} 

En la implementación de ITaskprovider a continuación, al ver que el IUserTask y IIdentityTask se está inyectando de propiedad en lugar del constructor. La razón es que Windsor instancia automáticamente las propiedades inyectadas en tiempo de ejecución cuando se accede, por lo que no tengo que poner todas las dependencias de must injected en el constructor.inyección de dependencias

public class TaskProvider : ITaskProvider 
    { 
     public IUserTasks UserTasks { get; set; } 

     public IIdentityTasks IdentityTasks { get; set; } 

     public T GetTask<T>() 
     { 
      Type type = typeof(T); 
      if (type == typeof(IUserTasks)) return (T)this.UserTasks; 
      if (type == typeof(IIdentityTasks)) return (T)this.IdentityTasks; 

      return default(T); 
     } 
    } 

En el controlador, estoy inyectando el ITaskProvider en el constructor.

public ITaskProvider TaskProvider { get; set; } 

public AuctionsController(ITaskProvider taskProvider) 
     { 
      TaskProvider = taskProvider; 
     } 

Y aquí llamo al proveedor de tareas y sus métodos bien.

public ActionResult Index() 
{ 
var userTasks = TaskProvider.GetTask<IUserTasks>(); 
var user = userTasks.FindbyId(guid); 

} 

Hasta aquí, todo funciona bien.

Me han dicho que esto es más como un patrón de localización de servicios y está violando el patrón de inyección de dependencia y quiero saber qué está violando aquí.

Respuesta

4

Para mí, no hay ninguna violación contra el DI en su código, con respecto wikipedia:

núcleo principal de la conducta independiente de resolución de dependencias

Pero el lado malo de su controlador tiene demasiado conocimiento En algunos casos (si no programa con cuidado) puede violar el Law Of Demeter

eche un vistazo a su código:

public ActionResult Index() 
{ 
var userTasks = TaskProvider.GetTask<IUserTasks>(); 
var user = userTasks.FindbyId(guid); 
} 
+0

Gracias por estas cosas útiles. – Murat

2

Si el controlador requiere una instancia de IUserTasks, sería más sencillo si recibiera una directamente del contenedor. Esencialmente, el TaskProvider es solo un contenedor alrededor del contenedor de todos modos, ya que es donde se obtienen las instancias UserTasks y IdentityTasks.

+0

Sí, eso es solo una envoltura.¿Todavía está violando el patrón de inyección de dependencia? – Murat

+1

@Murat - No es realmente una violación si se inyecta a sus dependientes, simplemente no proporciona ningún valor. – Lee

2

Está utilizando Dependency Injection para inyectar lo que efectivamente es el "Localizador de servicios" en el controlador en lugar de inyectar una implementación de IUserTasks y IIdentityTasks.

Su controlador real realmente tiene dependencias en IUserTasks y IIdentityTasks pero no las inyecta directamente en su controlador, sino que decide utilizar el "Localizador de servicios" o el Proveedor de tareas y por lo tanto ha inyectado una dependencia en el localizador de servicios que en el el ejemplo parece no proporcionar nada que no se pueda hacer inyectando directamente las dependencias verdaderas.

1

Debe inyectar IUserTask y IIdentityTask en el constructor del controlador, ya que no hay ganancia en el uso del TaskProvider. Además de eso, en la forma en que lo hiciste, te pierdes algunos controles de tiempo de compilación. Por ejemplo, puede llamar a TaskProvider.GetTask() y esperar a explotar en tiempo de ejecución. Debería, al menos, poner alguna restricción en ese parámetro genérico (si es posible que ambas interfaces hereden del elemento primario común).

En cuanto a la "violación", debe tener en cuenta que no está inyectando las dependencias en el controlador. Estás proporcionando una forma de recuperarlos.

Cuestiones relacionadas