在阅读了一些关于DI,Repository Pattern的文章之后......我用Asp.Net MVC创建了一个项目。以下是一些课程。它有效,但我想知道我做的是标准的吗?这是正确的模式吗?如果不是,我该如何调整以使其更好?
提前谢谢。
IGenericRepository接口:
public interface IGenericRepository<TEntity>: IDisposable where TEntity : class
{
IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "");
bool Contains(Expression<Func<TEntity, bool>> predicate);
TEntity GetById(params object[] keys);
TEntity Find(Expression<Func<TEntity, bool>> predicate);
TEntity Insert(TEntity t);
void Delete(TEntity t);
int Delete(Expression<Func<TEntity, bool>> predicate);
int Update(TEntity t);
int Count { get; }
}
GenericRepository类:(稍后我将实现这些函数)
public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity:class
{
internal GMSDbContext db;
internal DbSet<TEntity> dbSet;
public GenericRepository(GMSDbContext dbContext)
{
db = dbContext;
dbSet = db.Set<TEntity>();
}
public int Count
{
get
{
throw new NotImplementedException();
}
}
public bool Contains(Expression<Func<TEntity, bool>> predicate)
{
throw new NotImplementedException();
}
public int Delete(Expression<Func<TEntity, bool>> predicate)
{
throw new NotImplementedException();
}
public void Delete(TEntity t)
{
throw new NotImplementedException();
}
public TEntity Find(Expression<Func<TEntity, bool>> predicate)
{
throw new NotImplementedException();
}
public IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "")
{
throw new NotImplementedException();
}
public TEntity GetById(params object[] keys)
{
throw new NotImplementedException();
}
public TEntity Insert(TEntity t)
{
throw new NotImplementedException();
}
public int Update(TEntity t)
{
throw new NotImplementedException();
}
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
db.Dispose();
}
disposedValue = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
IAccountRepository接口:
public interface IAccountRepository : IGenericRepository<Account>
{
}
AccountRepository类:
public class AccountRepository: GenericRepository<Account>,IAccountRepository
{
public AccountRepository(GMSDbContext db) : base(db) { }
}
IUnitOfWork界面:
public interface IUnitOfWork: IDisposable
{
void SaveChanges();
IAccountRepository AccountRepository { get; }
}
UnitOfWork类:
public class UnitOfWork : IUnitOfWork
{
private GMSDbContext db;
private IAccountRepository accountRepo;
public UnitOfWork()
{
db = new GMSDbContext();
}
public IAccountRepository AccountRepository
{
get
{
if (accountRepo != null) return accountRepo;
else return new AccountRepository(db);
}
}
public void SaveChanges()
{
db.SaveChanges();
}
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
db.Dispose();
}
disposedValue = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
IAccountService接口:
public interface IAccountService
{
int CheckLogin(string username, string password);
Account GetAccountByUsername(string username);
}
AccountService类:
public class AccountService : IAccountService, IDisposable
{
private IUnitOfWork unitOfWork;
public AccountService(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
#region Serivce Methods
public int CheckLogin(string username, string password)
{
var entity = unitOfWork.AccountRepository.
Find(o => o.Username.Equals(username, StringComparison.OrdinalIgnoreCase)
&& o.Password.Equals(password, StringComparison.OrdinalIgnoreCase));
if (entity == null) return -1;
else {
if (entity.IsEnabled) return 0;
else return -2;
}
}
public Account GetAccountByUsername(string username)
{
throw new NotImplementedException();
}
#endregion
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
unitOfWork.Dispose();
}
disposedValue = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
AccountController类:
public class AccountController : Controller
{
private IAccountService accountService;
public AccountController(IAccountService accountService)
{
this.accountService = accountService;
}
// GET: Admin/Account
public ActionResult Index()
{
return View();
}
}
我对IOC容器使用Simple Injector:
public static class SimpleInjectorInitializer
{
/// <summary>Initialize the container and register it as MVC3 Dependency Resolver.</summary>
public static void Initialize()
{
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
InitializeContainer(container);
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}
private static void InitializeContainer(Container container)
{
// For instance:
container.Register<IAccountService, AccountService>(Lifestyle.Scoped);
container.Register<IUnitOfWork, UnitOfWork>(Lifestyle.Scoped);
}
}
答案 0 :(得分:0)
在EntityFramework上下文is not a good idea之上的存储库和UnitOfWork。
当您使用EntityFramework并实例化DbContext时 - 您正在创建一个新的UnitOfWork。
创建IGenericRepository<TEntity>
然后为每个实体实施它没有意义。因为您只是包装DbContext并创建不需要的代码。
如果您不想在控制器中创建/注入DbContext实例(例如,用于单元测试)。您可以创建一个IGMSDbContext
接口及其实现,如:
public interface IGMSDbContext
{
DbSet<Account> Accounts { get; set; }
int SaveChanges();
}
public class GMSDbContext: DbContext, IGMSDbContext
{
public DbSet<Account> Accounts { get; set; }
public GMSDbContext(string connection) : base(connection)
{
}
public GMSDbContext() : base("your connection string name")
{
}
}
然后只需将IGMSDbContext
注入您的服务:
private IGMSDbContext dbContext;
public AccountService(IGMSDbContext dbContext)
{
this.dbContext = dbContext;
}
通过这种方式,您可以在代码this.dbContext.Accounts.Where....
以上实施有许多好处:
IGenericRepository<T>