design-patterns - gof - javascript design patterns pdf
No se puede combinar Factory/DI (2)
Solo asuma que tengo una clase Foo, que tiene dos dependencias: un ISerializer<T>
y un IFileAccessHandler
.
Ahora esta clase también tiene otras dependencias, dependencias funcionales. No quiero que nadie cree una instancia de esta clase en un estado no válido, por lo que también tendría que pasar un objeto de dominio en el constructor.
Pero ¿cómo puedo hacer que IoC maneje eso cuando también sé qué objeto de dominio pasar en el momento en que estoy creando la clase Foo?
Hice el objeto de dominio una propiedad que he establecido por una fábrica. Por lo tanto, la fábrica realiza una llamada al Localizador de servicios para obtener una clase "Foo" correctamente instanciada con sus dependencias, y luego la rellena con el objeto de dominio correcto y lo devuelve.
¿Pero es esta la mejor manera de hacerlo? Hubiera preferido que el objeto de dominio fuera parte de mi constructor para que fuera realmente necesario para trabajar con "Foo".
¿Algunas ideas? ¿Me estoy perdiendo de algo?
La solución predeterminada para DI cuando no se puede conectar un tipo concreto en el momento del registro es utilizar una fábrica abstracta
En su caso, definiría una interfaz IFooFactory:
public interface IFooFactory
{
Foo Create(DomainClass dc);
}
Esto le permitirá definir una implementación concreta que conozca sus servicios de infraestructura.
public class FooFactory : IFooFactory
{
private readonly ISerializer serializer;
private readonly IFileAccessHandler fileHandler;
public FooFactory(ISerializer serializer, IFileAccessHandler fileHandler)
{
if(serializer == null)
{
throw new ArgumentNullException("serializer");
}
if(fileHandler == null)
{
throw new ArgumentNullException("fileHandler");
}
this.serializer = serializer;
this.fileHandler = fileHandler;
}
public Foo Create(DomainClass dc)
{
return new Foo(this.serializer, this.fileHandler, dc);
}
}
De esta manera puede proteger los invariantes de su clase Foo, lo que le permite permanecer con la inyección de Constructor .
En el contenedor DI, puede registrar IFooFactory y la implementación correspondiente. En cualquier lugar donde tengas una instancia de DomainClass y necesites una instancia de Foo, entonces tomarías una dependencia de IFooFactory y la usarías.
También estoy luchando con este problema. El ejemplo de Mark está limitado porque FooFactory está creando una clase concreta Foo. ¿Qué ocurre si se trata de crear un IFoo donde la implementación se determina durante la configuración de inicio? Esto implicaría que para cada implementación alternativa de IFoo (FooA, FooB, etc.) necesitaría una implementación concreta de la fábrica correspondiente (FooAFactory, FooBFactory, etc.). Esto me parece redundante.
Si la fábrica se define en el mismo nivel que la implementación y la inicialización del contenedor, no veo la debilidad de hacer referencia al contenedor por parte de la fábrica. Todavía evita que las referencias del contenedor se filtren en el resto de su aplicación.
Atentamente,
Metro.