Ich habe ein generisches Repository-Muster mit UnitOfWork und ich verwende IoC. Anders als die vom Repository verwendeten Basismethoden habe ich einige benutzerdefinierte Methoden. Anstatt die gesamten IRepository-Methoden erneut zu implementieren, habe ich von der GenericRepository-Klasse geerbt.Generisches Repository mit UnitOfWork mit IoC Benutzerdefinierte Methoden
Hier ist meine UnitofWork Umsetzung:
public interface IUnitOfWork<T> : IDisposable where T : DbContext
{
int Save();
T Context { get; }
}
public class UnitOfWork<T> : IUnitOfWork<T> where T : MyContext, new()
{
private readonly T _context;
public UnitOfWork()
{
_context = new T();
}
public UnitOfWork(T Context)
{
_context = Context;
}
public int Save()
{
return _context.SaveChanges();
}
public T Context
{
get
{
return _context;
}
}
public void Dispose()
{
_context.Dispose();
}
}
Das ist mein Repository Implementierung:
public interface IGenericRepository
{
IQueryable<T> All<T>() where T : class;
void Remove<T>(int id)where T : class;
void Remove<T>(T entity) where T : class;
void RemoveRange<T>(IList<T> entities) where T : class;
T Find<T>(int id) where T : class;
void Add<T>(T entity) where T : class;
void AddRange<T>(IList<T> entities) where T : class;
void Update<T>(T entity) where T : class;
int SaveChanges();
}
public class GenericRepository<C> : IGenericRepository where C : MyContext
{
protected readonly C _context;
public GenericRepository(IUnitOfWork<C> unitOfWork)
{
_context = unitOfWork.Context;
}
public int SaveChanges()
{
return _context.SaveChanges();
}
public IQueryable<T> All<T>() where T : class
{
return _context.Set<T>();
}
public void Remove<T>(int id) where T : class
{
T entity = _context.Set<T>().Find(id);
if (entity != null)
{
_context.Set<T>().Remove(entity);
}
}
public void Remove<T>(T entity) where T : class
{
if (entity != null)
{
_context.Set<T>().Remove(entity);
}
}
public void RemoveRange<T>(IList<T> entities) where T : class
{
if (entities.Count > 0)
{
_context.Set<T>().RemoveRange(entities);
}
}
public T Find<T>(int id) where T : class
{
return _context.Set<T>().Find(id);
}
public void Add<T>(T entity) where T : class
{
_context.Set<T>().Add(entity);
}
public void AddRange<T>(IList<T> entities) where T : class
{
_context.Set<T>().AddRange(entities);
}
public void Update<T>(T entity) where T : class
{
_context.Set<T>().Attach(entity);
_context.Entry(entity).State = System.Data.Entity.EntityState.Modified;
}
}
Hier ist ein Beispiel Custom-Repository:
public interface IUserAccountRepository : IGenericRepository
{
UserAccount Find(string email, string password);
bool CheckDuplicate(string email);
}
public class UserAccountRepository<C> : GenericRepository<C> where C : CSharpAssigmentContext, IUserAccountRepository
{
protected readonly C _context;
public UserAccountRepository(IUnitOfWork<C> unitOfWork)
{
_context = unitOfWork.Context;
}
public int SaveChanges()
{
return _context.SaveChanges();
}
/// <summary>
/// Find user by email and password
/// </summary>
public UserAccount Find(string email, string password)
{
return _context.Set<UserAccount>().Where(ua => ua.Email == email && ua.Password == password).FirstOrDefault(null);
}
/// <summary>
/// Check wether user exists or not
/// </summary>
public bool CheckDuplicate(string email)
{
return _context.Set<UserAccount>().Any(ua => ua.Email == email);
}
public IQueryable<T> All<T>() where T : class
{
return _context.Set<T>();
}
public void Remove<T>(int id) where T : class
{
T entity = _context.Set<T>().Find(id);
if (entity != null)
{
_context.Set<T>().Remove(entity);
}
}
public void Remove<T>(T entity) where T : class
{
if (entity != null)
{
_context.Set<T>().Remove(entity);
}
}
public void RemoveRange<T>(IList<T> entities) where T : class
{
if (entities.Count > 0)
{
_context.Set<T>().RemoveRange(entities);
}
}
public T Find<T>(int id) where T : class
{
return _context.Set<T>().Find(id);
}
public void Add<T>(T entity) where T : class
{
_context.Set<T>().Add(entity);
}
public void AddRange<T>(IList<T> entities) where T : class
{
_context.Set<T>().AddRange(entities);
}
public void Update<T>(T entity) where T : class
{
_context.Set<T>().Attach(entity);
_context.Entry(entity).State = System.Data.Entity.EntityState.Modified;
}
Hier ist meine Unity IoC Code:
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
//UnitOfWork and GenericRepository
container.RegisterType(typeof(IUnitOfWork<CSharpAssigmentContext>),typeof(UnitOfWork<CSharpAssigmentContext>), new HierarchicalLifetimeManager());
container.RegisterType(typeof(IGenericRepository), typeof(GenericRepository<CSharpAssigmentContext>), new HierarchicalLifetimeManager());
//I keep receiving compile ERROR here
container.RegisterType(typeof(IUserAccountRepository), typeof(UserAccountRepository<CSharpAssigmentContext>), new HierarchicalLifetimeManager());
//Services
container.RegisterType(typeof(IUsersAccountsService), typeof(UsersAccountsService), new TransientLifetimeManager());
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
}
Wie im Code erwähnt, halte ich einen Fehler zur Kompilierzeit für den folgenden Code erhalten:
container.RegisterType(typeof(IUserAccountRepository), typeof(UserAccountRepository<CSharpAssigmentContext>), new HierarchicalLifetimeManager());
Der Fehler ist:
Der Typ mycontext nicht als Typ verwendet werden kann, Parameter C im generischen Typ oder in der Methode. Es gibt keine implizite Referenzkonvertierung von MyContext nach IMyClassRepository.
Wie löst man diesen Fehler? Ist meine Implementierung für benutzerdefinierte Repositories korrekt?
Können Sie Ihre UserAccountRepository-Klassensignatur anzeigen? –