Ich habe ein Problem, wo ich eine Reihe von Objekten in der Business-Schicht, die eine Vererbungsstruktur zwischen ihnen haben und ich habe auch eine Reihe von DAL-Objekte, die sie unterstützen, die eine etwa parallele Vererbungsstruktur haben. Das Problem, auf das ich gestoßen bin, besteht darin, dass der DAL-Typ auf mehreren Ebenen der BOL-Vererbung verstanden werden muss, z. B. muss ein Basisgeschäftsobjekt in der Lage sein, auf die Eigenschaften des Basis-DAL-Objekts zuzugreifen, aber dieselbe Eigenschaft muss später die spezifische Instanz liefern.
Da C# keine Rückgabekovarianz unterstützt, kann ich nicht einfach einen spezifischeren Typ in einer Override-Deklaration verwenden. Ich bin auch nicht in der Lage, Generika zu verwenden, da ich eine konkrete Spezifikation des Typs tun müsste, um sie zu verwenden, und das bricht weitere Vererbung aus dem gleichen Grund der Rückgabekovarianz. Die einzige Lösung, die mir bisher eingefallen ist, scheint sehr beängstigend zu sein, daher wollte ich sie hier posten, um Feedback oder alternative Ideen zu erhalten.
Es scheint, dass dieses Problem durch die Definition einer generischen Schnittstelle gelöst werden kann IHasDal<TDalType>
. Ich kann dann festlegen, dass die BOLBase : IHasDal<BaseDAL>
. Dies erfordert dann eine Implementierung der Eigenschaft .Dal auf BOLBase. Für BolChild wird sie deklariert als BOLChild : BOLBase, IHasDal<ChildDAL>
und spezifiziert dann eine .Dal
Eigenschaft, die vom Typ ChildDAL
. Obwohl diese beiden Befehle nicht miteinander verbunden und spezifisch für die Ebene der Klasse sind, in der sie sich befinden, habe ich sie miteinander verknüpft, indem ich ein privates Feld in BOLBase
vom Typ BaseDAL
. Ich kann dann werfen es über AS für jedes Kind Eigenschaft Implementierung.
Theoretisch scheint es so, als ob ich damit das, was ich suche, mit minimalen Problemen erreichen könnte. Es wird entweder für ein Objekt verfügbar sein, das eine IHasDal
des von mir angegebenen Typs oder für einen bestimmten BOLBase
abgeleitete Klasse. Es fühlt sich immer noch hässlich an, da es sich effektiv auf das Ausblenden von Methoden zu stützen scheint, aber ich kann mir nichts Besseres vorstellen.
public interface IHasDal<TDalType>
where TDalType : BaseDal
{
TDalType Dal { get; set; }
}
public class BaseDal
{
}
public class BaseEntity : IHasDal<BaseDal>
{
protected BaseDal _dal;
public BaseDal Dal
{
get
{
return (BaseDal)_dal;
}
set
{
_dal = value;
}
}
}
public class ChildDal : BaseDal
{
}
public class ChildEntity : BaseEntity, IHasDal<ChildDal>
{
public ChildDal Dal
{
get
{
return this._dal as ChildDal;
}
set
{
this._dal = value;
}
}
}