2011-12-05 1269 views
17

Veo a los desarrolladores principales escribiendo código como este y al leer el libro de Mark Seemann "Inyección de Dependencia en .NET" Me pregunto si el "nuevo" específico es "extraño", por lo tanto, "Inyección Bastard" ??¿Es este un buen ejemplo del "anti-patrón de inyección Bastard"?

public class SessionInitServiceManager 
{ 
    protected readonly ICESTraceManager _traceManager; 
    protected readonly ILogger _logger; 
    protected readonly IAggregateCalls _aggregator; 
    protected readonly IMultiCoreRepository _repository; 

    public SessionInitServiceManager(ICESTraceManager traceManager, 
            ILogger logger, 
            IAggregateCalls aggregator, 
            IMultiCoreRepository repository) 
    { 
     _traceManager = traceManager; 
     _logger = logger; 
     _aggregator = aggregator; 
     _repository = repository; 
    } 

    public SessionInitServiceManager() : this(new CESTraceManager(), 
               new Logger("BusinessServices.authenticateUser"), 
               new Aggregator(), 
               new RepositoryFactory().BuildMultiCoreRepository()) { } 
+0

Como acotación al margen, cuatro parámetros está empujando el límite de DI sensible (el autor afirma que su límite es generalmente cuatro) porque te obliga a comenzar a cuestionar si SessionInitServiceManager está violando a SRP. Pasar a otra clase de administrador también sugiere que este puede ser el caso. – RichK

+0

Sí, recuerdo haber leído que 3-4 es un límite general. Cualquier buen ejemplo de cómo evitar este nuevo problema con o sin un contenedor de IOC como unity.? –

+4

La respuesta depende de si alguna de las implementaciones 'predeterminadas' están definidas dentro de la misma biblioteca o en una biblioteca diferente ary. http://stackoverflow.com/questions/6733667/is-there-an-alternative-to-bastard-injection-aka-poor-mans-injection-via-defa/6739953#6739953 –

Respuesta

9

Esto ciertamente parece un ejemplo clásico de inyección de bastard. La razón es porque tiene lo que parece ser cuatro valores predeterminados en el extranjero. El valor predeterminado externo se refiere a un valor predeterminado en el que el tipo proviene de un módulo/proyecto/DLL diferente. Yo incluiría espacio de nombres propyl en esa definición, porque los espacios de nombre pueden significar límites en los que en un punto futuro se divide en su propio módulo. Esto es más de ser consciente de eso cuando decides utilizar un valor predeterminado local (¿lo dividiría en su propio módulo en el futuro?).

La forma en que esto no sería la inyección de bastard sería que todas estas clases viven dentro del mismo módulo. Lo que lo hace tan malo es que arrastras las dependencias, y ahora tu clase está estrechamente unida a estas clases. Si elijo usar mi propia versión de registro, tengo que llevar la DLL para el registro, etc., aunque no la use, negando los beneficios del diseño modular de la aplicación.

+0

Eso me suena bien. ¡Gracias! –

0

Ocurrió que tomé prestado ese libro, la inyección de dependencia en .NET, de un amigo. Veo lo que dices. Creo que esto es "inyección bastarda". Es un término brutal, pero supongo que apropiado después de todo ColdFusion (tos) tiene una etiqueta "CFABORT" como parte del lenguaje.

Además, me di cuenta de un buen artículo, entrada de blog How not to do dependency injection - the static or singleton container.

Básicamente, antes de empezar, vamos a dejar algo fuera del camino:

inyección de dependencia = Usando un contenedor IoC "

Aquí está el truco," Este es el nacimiento del contenedor estático. En lugar de cambiar el constructor del controlador para disfrutar de la dependencia, sólo estamos cambiando la línea donde el servicio se crea una instancia de resolverlo utilizando el contenedor en su lugar."

public class HomeController 
{ 
    private readonly IExampleService _service; 

    public HomeController() 
    { 
     _service = Container.Instance.Resolve<IExampleService>(); 
    } 

    public ActionResult Index() 
    { 
     return View(_service.GetSomething()); 
    } 
} 
+3

Dentro del constructor predeterminado, en realidad está utilizando el anti-patrón del localizador de servicios, ¿cómo sabe que el contenedor tendrá un IExampleService para usted? Y si no? en el método Index NullArgumentException, y en tiempo de diseño parece "fino". Esto no usa un contenedor IoC, esto aplica DI de forma incorrecta –

Cuestiones relacionadas