繁体   English   中英

标准化存储库,UnitOfWork,IOC容器Asp.Net MVC

[英]Standardize Repository, UnitOfWork, IOC Container Asp.Net MVC

阅读了有关DI,存储库模式等的一些文章之后,我用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容器:

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);
    }
}

在EntityFramework上下文之上的存储库和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....使用上下文。

上面的实现有很多好处:

  1. 您不必重新发明轮子,因为IGMSDbContext包含了您需要的一切(LINQ,UnitOfWork)。
  2. 您不需要实现和维护IGenericRepository<T>代码
  3. 您仍然可以轻松模拟IGMSDbContext进行单元测试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM