Ich arbeite an einer C# MVC-Anwendung mit dem Repository-Muster. Ich verwende Unity als meinen IoC, um mein Repository in der MVC-Anwendung zu implementieren.C# generische Typen und Repository-Muster
Ich habe den folgenden generischen Typ erstellt mit dem Ziel, Code-Replikation in meinen Anwendungen zu minimieren. Hier ist ein Beispiel:
public abstract class GenericRepository<T, C> : IDisposable,IGenericRepository<T> where T : class where C : DbContext, new()
public async void AddObjectAsync<T>(T entity) where T : class
{
try
{
// Validate that that there is not an existing object in the database.
var x = _context.Entry(entity);
if (!Exists(entity))
{
_context.Set<T>().Add(entity); // Add the entry if it does not exist.
_context.SaveChanges();
}
else
{
UpdateObjectAsync(entity); // Update the entry if it did exist.
}
}
catch
{
throw;
}
Das ist großartig zu arbeiten, wenn ich eine TPC oder TPH-Strategie verwenden, aber es nicht gut spielt mit einer TPT-Strategie. Ein Beispiel:
public abstract class Component
{
[Key]
public Guid ComponentId { get; set; }
public string Manufacturer { get; set; }
}
public class SpecialComponent : Component
{
public string ExtraSpecialProperty { get; set; }
}
Meine Umsetzung im ComponentRepository:
public class ComponentRepository : GenericRepository<Component, HappyDbContext>, IComponentRepository
{
public async void AddComponentAsync<T>(T component) where T : class
{
try
{
if(component != null)
{
AddObjectAsync(component);
}
else
{
throw new ArgumentNullException();
}
}
catch (ArgumentNullException ex)
{
_logger.WriteErrorLogAsync(ex);
throw ex;
}
}
Die erste Zeile dieses Codeblock ist das, was Ich habe Probleme mit. Um den Typ GenericRepository zu initialisieren, muss ich eine Klasse für T einfügen. In diesem Fall ist der DbContext C immer derselbe, so dass er nicht von Belang ist.
Wie kann ich ein vollständig generisches Muster implementieren, das mit geerbten Typen funktioniert? Wenn es eine kleine Anzahl von Gegenständen wäre, wäre ich weniger besorgt darüber, aber das ist in dieser Situation nicht der Fall. Ich denke, dass es sicherlich einen besseren Weg gibt, damit umzugehen, deshalb richte ich mich an euch alle für eure Beiträge.
Was ist die Beziehung zwischen den 'T' Parametern auf dem GenericRepository-Klasse und der 'T'-Parameter auf AddObjectAsync? – StriplingWarrior
Wäre dies eine Situation, in der Sie die Komposition über die Vererbung verwenden könnten? Wenn ComponentRepository eine spezialisierte Factory injiziert, die in der Lage ist, GenericRepository-Instanzen zu konstruieren, kann 'AddComponentAsync' diese Factory aufrufen, um basierend auf dem für diese Methode bereitgestellten Typ ein stark generisch typisiertes Repository zu erstellen. – StriplingWarrior
Entschuldigung, ich habe Ihren Kommentar falsch gelesen. Sie sind gleich. Wenn wir die Entity "Component" übergeben, wird AddObjectAsync vom Typ sein und einen Methodenparameter von (Component entity) erwarten. –