¿Por qué no utilizar un contenedor de IoC para resolver dependencias de entidades/objetos comerciales?

Resuelto Casey Wilkins asked hace 13 años • 2 respuestas

Entiendo el concepto detrás de DI, pero recién estoy aprendiendo qué pueden hacer los diferentes contenedores de IoC. Parece que la mayoría de la gente aboga por el uso de contenedores IoC para conectar servicios sin estado, pero ¿qué pasa con su uso para objetos con estado como entidades?

Ya sea correcto o incorrecto, normalmente relleno mis entidades con comportamiento, incluso si ese comportamiento requiere una clase externa. Ejemplo:

public class Order : IOrder
{

    private string _ShipAddress;
    private IShipQuoter _ShipQuoter;

    public Order(IOrderData OrderData, IShipQuoter ShipQuoter)
    {
        // OrderData comes from a repository and has the data needed 
        // to construct order
        _ShipAddress = OrderData.ShipAddress;  // etc.
        _ShipQuoter = ShipQuoter;

    }

    private decimal GetShippingRate()
    {
        return _ShipQuoter.GetRate(this);
    }
}

Como puede ver, las dependencias son Constructor Injected. Ahora un par de preguntas.

  1. ¿Se considera una mala práctica que sus entidades dependan de clases externas como ShipQuoter? Eliminar estas dependencias parece llevarme hacia un dominio anémico, si entiendo correctamente la definición.

  2. ¿Es una mala práctica utilizar un contenedor de IoC para resolver estas dependencias y construir una entidad cuando sea necesario? ¿Es posible hacer esto?

Gracias por cualquier idea.

Casey Wilkins avatar Jan 29 '11 10:01 Casey Wilkins
Aceptado

La primera pregunta es la más difícil de responder. ¿Es una mala práctica que las entidades dependan de clases externas? Ciertamente no es lo más común que se puede hacer.

Si, por ejemplo, inyecta un Repositorio en sus Entidades, efectivamente tiene una implementación del patrón Active Record . A algunas personas les gusta este patrón por la conveniencia que brinda, mientras que otras (como yo) lo consideran un olor a código o un antipatrón porque viola el Principio de Responsabilidad Única (SRP).

Se podría argumentar que inyectar otras dependencias en las Entidades lo llevaría en la misma dirección (lejos de SRP). Por otro lado, ciertamente tiene razón en que si no hace esto, la atracción será hacia un modelo de dominio anémico .

Luché con todo esto durante mucho tiempo hasta que encontré el artículo (abandonado) de Greg Young sobre DDDD donde explica por qué la arquitectura estereotipada de n niveles/n capas siempre será CRUDy (y por lo tanto bastante anémica).

Mover nuestro enfoque al modelado de objetos de dominio como comandos y eventos en lugar de sustantivos parece permitirnos construir un modelo de dominio orientado a objetos adecuado.

La segunda pregunta es más fácil de responder. Siempre puedes usar Abstract Factory para crear instancias en tiempo de ejecución . Con Castle Windsor, puede incluso utilizar Typed Factory Facility, aliviando así la carga de implementar las fábricas manualmente.

Mark Seemann avatar Jan 29 '2011 12:01 Mark Seemann

Sé que esta es una publicación antigua pero quería agregarla. La entidad de dominio no debe persistir incluso si pasa un repositorio resumido en ctor. La razón por la que sugiero esto no es simplemente que viola SRP, sino que también es contrario a la agregación de DDD. Permítanme explicarles, DDD es adecuado para aplicaciones complejas con gráficos inherentemente profundos, por lo tanto, usamos raíces agregadas o compuestas para persistir los cambios en los "hijos" subyacentes, de modo que cuando inyectamos persistencia en los niños individuales violamos la relación que los niños tienen con el raíz compuesta o agregada que debe estar "a cargo" del ciclo de vida o agregación. Por supuesto, la raíz compuesta o el agregado tampoco conservan su propio gráfico. Otro problema con la inyección de dependencias de objetos DDD es que un objeto de dominio inyectado efectivamente no tiene estado hasta que ocurre algún otro evento para hidratar su estado. Cualquier consumidor del código se verá obligado a iniciar o configurar el objeto de dominio primero antes de poder invocar un comportamiento empresarial que viole la encapsulación.

user1538467 avatar Sep 22 '2017 13:09 user1538467