User
and Role
are just examples; also, code is sparse on purpose (i.e. for demonstration purposes only).
Thoughts? (e.g. good, bad, etc.)
Interfaces
public interface IEntity
{
int Id { get; }
}
public interface IUser
: IEntity
{
string Username { get; }
string Email { get; }
ICollection<IRole> Roles { get; }
}
public interface IRole
: IEntity
{
string Name { get; }
ICollection<IUser> Users { get; }
}
public interface IContext<TEntity>
: IDisposable
where TEntity : class, IEntity
{
IDbSet<TEntity> Entities();
int SaveChanges();
}
public interface IUserContext<TUser>
: IContext<TUser>
where TUser : class, IUser
{
}
public interface IRoleContext<TRole>
: IContext<TRole>
where TRole : class, IRole
{
}
public interface IRepository<TEntity>
: IDisposable
where TEntity : class, IEntity
{
TEntity Find(int id);
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> filter);
void Add(TEntity entity);
void Remove(TEntity entity);
}
public interface IUserRepository<TUser>
: IRepository<TUser>
where TUser : class, IUser
{
}
public interface IRoleRepository<TRole>
: IRepository<TRole>
where TRole : class, IRole
{
}
public interface IUnitOfWork<TUser, TRole>
: IDisposable
where TUser : class, IUser
where TRole : class, IRole
{
IUserRepository<TUser> Users();
IRoleRepository<TRole> Roles();
int SaveChanges();
}
Classes
public abstract class Entity
: IEntity
{
public virtual int Id { get; set; }
}
public class User
: Entity, IUser
{
private ICollection<IRole> _roles;
public string Username { get; set; }
public string Email { get; set; }
public virtual ICollection<IRole> Roles
{
get { return _roles ?? (_roles = new Collection<IRole>()); }
set { _roles = value; }
}
}
public class Role
: Entity, IRole
{
private ICollection<IUser> _users;
public string Name { get; set; }
public virtual ICollection<IUser> Users
{
get { return _users ?? (_users = new Collection<IUser>()); }
set { _users = value; }
}
}
public abstract class Context<TContext, TEntity>
: DbContext, IContext<TEntity>
where TContext : DbContext
where TEntity : class, IEntity
{
static Context()
{
Database.SetInitializer<TContext>(null);
}
protected Context()
: this("name=DefaultConnection")
{
}
protected Context(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
public virtual IDbSet<TEntity> Entities()
{
return Set<TEntity>();
}
}
public class UserContext<TUser>
: Context<UserContext<TUser>, TUser>, IUserContext<TUser>
where TUser : class, IUser
{
public UserContext()
{
}
public UserContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
}
public class RoleContext<TRole>
: Context<RoleContext<TRole>, TRole>, IRoleContext<TRole>
where TRole : class, IRole
{
public RoleContext()
{
}
public RoleContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
}
public abstract class Repository<TEntity>
: IRepository<TEntity>
where TEntity : class, IEntity
{
private readonly IContext<TEntity> _context;
private bool _disposed;
protected Repository(IContext<TEntity> context)
{
_context = context;
_disposed = false;
}
public virtual TEntity Find(int id)
{
return _context.Entities().Find(id);
}
public virtual IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> filter = null)
{
return filter != null
? _context.Entities().Where(filter)
: _context.Entities();
}
public virtual void Add(TEntity entity)
{
_context.Entities().Add(entity);
}
public virtual void Remove(TEntity entity)
{
_context.Entities().Remove(entity);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_context.Dispose();
}
_disposed = true;
}
}
~Repository()
{
Dispose(false);
}
}
public class UserRepository<TUser>
: Repository<TUser>, IUserRepository<TUser>
where TUser : class, IUser
{
public UserRepository()
: this(new UserContext<TUser>())
{
}
public UserRepository(IUserContext<TUser> context)
: base(context)
{
}
}
public class RoleRepository<TRole>
: Repository<TRole>, IRoleRepository<TRole>
where TRole : class, IRole
{
public RoleRepository()
: this(new RoleContext<TRole>())
{
}
public RoleRepository(IRoleContext<TRole> context)
: base(context)
{
}
}
public class UnitOfWork<TUser, TRole>
: IUnitOfWork<TUser, TRole>
where TUser : class, IUser
where TRole : class, IRole
{
private readonly IUserContext<TUser> _userContext;
private readonly IRoleContext<TRole> _roleContext;
private readonly IUserRepository<TUser> _userRepository;
private readonly IRoleRepository<TRole> _roleRepository;
private bool _disposed;
public UnitOfWork()
: this(new UserContext<TUser>(), new RoleContext<TRole>())
{
}
public UnitOfWork(IUserContext<TUser> userContext, IRoleContext<TRole> roleContext)
{
_userContext = userContext;
_roleContext = roleContext;
_userRepository = new UserRepository<TUser>(_userContext);
_roleRepository = new RoleRepository<TRole>(_roleContext);
_disposed = false;
}
public IUserRepository<TUser> Users()
{
return _userRepository;
}
public IRoleRepository<TRole> Roles()
{
return _roleRepository;
}
public int SaveChanges()
{
return _userContext.SaveChanges() + _roleContext.SaveChanges();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_userContext.Dispose();
_roleContext.Dispose();
_userRepository.Dispose();
_roleRepository.Dispose();
}
_disposed = true;
}
}
~UnitOfWork()
{
Dispose(false);
}
}