Sto lavorando a un'applicazione C# MVC utilizzando il modello di repository. Sto usando Unity come mio IoC per implementare il mio repository all'interno dell'applicazione MVC.C# tipi generici e modello di repository
Ho creato il seguente tipo generico con l'obiettivo di ridurre al minimo la replica del codice in tutte le mie applicazioni. Ecco un esempio:
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;
}
Questo sta lavorando molto quando uso una strategia TPC o TPH, tuttavia non gioca bene con una strategia TPT. Un esempio:
public abstract class Component
{
[Key]
public Guid ComponentId { get; set; }
public string Manufacturer { get; set; }
}
public class SpecialComponent : Component
{
public string ExtraSpecialProperty { get; set; }
}
mia implementazione all'interno del 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;
}
}
La prima riga di questo blocco di codice è quello che sto avendo difficoltà con. Per inizializzare il tipo GenericRepository ho bisogno di inserire una classe per T. In questo caso il DbContext C sarà sempre lo stesso, quindi non è preoccupante.
Come posso implementare un modello completamente generico che funzioni con tipi ereditati? Se si trattasse di un numero limitato di elementi, sarei meno preoccupato, tuttavia non è il caso in questa situazione. Penso che ci sia sicuramente un modo migliore per gestirlo, quindi ti sto contattando per il tuo contributo.
Qual è il rapporto tra il parametro 'T' sulla Classe GenericRepository e il parametro 'T' su AddObjectAsync? – StriplingWarrior
Questa è una situazione in cui è possibile utilizzare la composizione sull'ereditarietà? Se ComponentRepository ha iniettato una factory specializzata in grado di costruire istanze di GenericRepository, quindi 'AddComponentAsync' potrebbe chiamare in quella factory per costruire un repository tipicamente generico basato sul tipo fornito per quel metodo. – StriplingWarrior
Spiacente, ho letto male il tuo commento. Loro sono la stessa cosa. Se passiamo l'Entità "Componente" AddObjectAsync sarà del tipo e aspettiamo un parametro metodo di (Entità componente). –