Ich verstehe das Konzept hinter DI, aber ich lerne gerade, was verschiedene IoC-Container können. Es scheint, dass die meisten Leute die Verwendung von IoC-Containern befürworten, um zustandslose Dienste zu verkabeln, aber was ist mit der Verwendung für zustandsbehaftete Objekte wie Entitäten?
Ob es richtig oder falsch ist, ich stopfe meine Entitäten normalerweise mit Verhalten, selbst wenn dieses Verhalten eine externe Klasse erfordert. Beispiel:
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);
}
}
Wie Sie sehen können, sind die Abhängigkeiten Konstruktor injiziert. Nun zu ein paar Fragen.
Wird es als schlechte Praxis angesehen, wenn Ihre Entitäten von externen Klassen wie dem ShipQuoter abhängig sind? Das Eliminieren dieser Abhängigkeiten scheint mich zu einer anämischen Domäne zu führen, wenn ich die Definition richtig verstehe.
Ist es eine schlechte Praxis, einen IoC-Container zu verwenden, um diese Abhängigkeiten aufzulösen und bei Bedarf eine Entität zu erstellen? Ist das möglich?
Vielen Dank für jeden Einblick.
quelle
Antworten:
Die erste Frage ist am schwierigsten zu beantworten. Ist es eine schlechte Praxis, wenn Entitäten von externen Klassen abhängig sind? Es ist sicherlich nicht die häufigste Sache.
Wenn Sie beispielsweise ein Repository in Ihre Entitäten einfügen, haben Sie effektiv eine Implementierung des Active Record-Musters . Einige Leute mögen dieses Muster aus Bequemlichkeitsgründen, während andere (wie ich) es als Codegeruch oder Anti-Muster betrachten, weil es gegen das Prinzip der Einzelverantwortung verstößt (SRP) .
Sie könnten argumentieren, dass das Einfügen anderer Abhängigkeiten in Entitäten Sie in die gleiche Richtung ziehen würde (weg von SRP). Auf der anderen Seite haben Sie sicherlich Recht, dass, wenn Sie dies nicht tun, die Anziehungskraft auf ein anämisches Domänenmodell gerichtet ist .
Ich hatte lange Zeit mit all dem zu kämpfen, bis ich auf Greg Youngs (aufgegebenes) Papier über DDDD stieß, in dem er erklärt, warum die stereotype n-Tier / n-Layer-Architektur immer CRUDy (und damit eher anämisch) sein wird.
Wenn wir uns darauf konzentrieren, Domänenobjekte als Befehle und Ereignisse anstelle von Substantiven zu modellieren , können wir möglicherweise ein geeignetes objektorientiertes Domänenmodell erstellen.
Die zweite Frage ist leichter zu beantworten. Sie können jederzeit eine Abstract Factory verwenden, um Instanzen zur Laufzeit zu erstellen . Mit Castle Windsor können Sie sogar die Typed Factory Facility nutzen, um die Fabriken nicht manuell zu implementieren.
quelle
Ich weiß, dass dies ein alter Beitrag ist, wollte ihn aber hinzufügen. Die Domänenentität sollte auch dann nicht bestehen bleiben, wenn Sie ein abstrahiertes Repository in ctor übergeben. Der Grund, warum ich dies vorschlage, ist nicht nur, dass es gegen SRP verstößt, sondern auch gegen die Aggregation von DDD. Lassen Sie mich erklären, dass DDD für komplexe Apps mit inhärent tiefen Diagrammen geeignet ist. Daher verwenden wir aggregierte oder zusammengesetzte Wurzeln, um Änderungen an den zugrunde liegenden "Kindern" beizubehalten. Wenn wir also den einzelnen Kindern Persistenz verleihen, verletzen wir die Beziehung, die Kinder zu den Kindern haben zusammengesetzte oder aggregierte Wurzel, die für den Lebenszyklus oder die Aggregation "verantwortlich" sein sollte. Natürlich bleibt die zusammengesetzte Wurzel oder das zusammengesetzte Aggregat auch nicht in ihrem eigenen Diagramm erhalten. Ein weiteres Problem beim Injizieren von Abhängigkeiten von DDD-Objekten besteht darin, dass ein injiziertes Domänenobjekt effektiv keinen Status hat, bis ein anderes Ereignis stattfindet, um seinen Status zu hydratisieren. Jeder Benutzer des Codes muss zuerst das Domänenobjekt initiieren oder einrichten, bevor er ein Geschäftsverhalten aufrufen kann, das die Kapselung verletzt.
quelle