簡體   English   中英

在ASP.NET MVC 5中使用具有通用存儲庫模式UnitOfWork的繼承接口的方法

[英]Using Method of Inherited Interface with Generic Repository Pattern, UnitOfWork in ASP.NET MVC 5

我的問題是從這里來的


我已經為國家存儲庫編寫了一個接口,並且我正在使用UnitOfWork跟蹤通用存儲庫,我還將ninject用於DI

public interface ICountryRepository : IRepository<Country>
{
    List<Country> GetAll();
}

已實施的國家/地區存儲庫界面,

public class CountryRepository : BaseRepository<Country>, ICountryRepository
{
    public CountryRepository(DbContextcontext) : base(context)
    {
    }

    public List<Country> GetAll(){
    // Not implemented
    }
} 

ICountryRepository接口中還有一個附加方法,我也已實現了它。 但是,當我需要使用UnitOfWork使用該方法時,就不能使用該方法。 那就是給System.NullReferenceException

我努力了,

ICountryRepository repository = UnitOfWork.Repository<Country>() as ICountryRepository;
return repository.GetAll();

垂頭喪氣的建議該方法,但如果不強制轉換,則無法訪問

給出了附加代碼,

實體


基礎實體

    public class BaseEntity
    {
        public int Id { get; set; }
    }

產品實體

public class Country : BaseEntity
{
    public string Name { get; set; }
}

儲存庫


接口

public interface IRepository<T>
{
    void Add(T entity);
}

基本資料庫

public class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity
{
    protected IDbContext _context;
    private readonly IDbSet<TEntity> _dbEntitySet;
    private bool _disposed;

    public BaseRepository(IDbContext context)
    {
        _context = context;
        _dbEntitySet = _context.Set<TEntity>();
    }

    public void Add(TEntity entity)
    {
        _context.SetAsAdded(entity);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public virtual void Dispose(bool disposing)
    {
        if (!_disposed && disposing)
        {
            _context.Dispose();
        }
        _disposed = true;
    }
}

工作單位


接口

public interface IUnitOfWork : IDisposable
{
    IRepository<TEntity> Repository<TEntity>() where TEntity : BaseEntity;

    void BeginTransaction();

    int Commit();

    Task<int> CommitAsync();

    void Rollback();

    void Dispose(bool disposing);

}

實施的工作單位

public class UnitOfWork : IUnitOfWork
{
    private readonly IDbContext _context;
    private bool _disposed;
    private Hashtable _repositories;

    public UnitOfWork(IDbContext context)
    {
        _context = context;
    }

    public IRepository<TEntity> Repository<TEntity>() where TEntity : BaseEntity
    {
        if (_repositories == null)
        {
            _repositories = new Hashtable();
        }

        var type = typeof(TEntity).Name;

        if (_repositories.ContainsKey(type))
        {
            return (IRepository<TEntity>)_repositories[type];
        }

        var repositoryType = typeof(BaseRepository<>);

        _repositories.Add(type, Activator.CreateInstance(repositoryType.MakeGenericType(typeof(TEntity)), _context));

        return (IRepository<TEntity>)_repositories[type];
    }

   /* Other Implementation
    *
    *
    *
    */
}

正如評論說,你解決類型的實例BaseRepository<Country> ,不是你的派生CountryRepository類,這是你想要的的情況下,以解決一個Country

一種粗略的硬編碼解決方案是用要解決的自定義類型替換要解決的通用存儲庫類型。 這樣的事情。 您將需要手動將條目添加到詞典中。

private static readonly Dictionary<Type, Type> s_RepositorySuperTypes = new Dictionary<Type, Type> {
    { typeof(BaseRepository<Country>), typeof(CountryRepository) }
};

public IRepository<TEntity> Repository<TEntity>() where TEntity : BaseEntity {
    if (_repositories == null) {
        _repositories = new Hashtable();
    }

    var type = typeof(TEntity).Name;
    if (_repositories.ContainsKey(type)) {
        return (IRepository<TEntity>)_repositories[type];
    }

    var closedRepositoryType = typeof(BaseRepository<>).MakeGenericType(typeof(TEntity));
    if (s_RepositorySuperTypes.ContainsKey(closedRepositoryType)) {
        closedRepositoryType = s_RepositorySuperTypes[closedRepositoryType];
    }
    _repositories.Add(type, Activator.CreateInstance(closedRepositoryType, _context));

    return (IRepository<TEntity>)_repositories[type];
}

您應該將自定義存儲庫方法擴展方法。

因此,如果您的額外方法稱為GetCountriesByContinent,則類似

public static class CountryRepository
{
    public static IEnumberable<Country> GetCountriesByContinent(this IRepository<Country> repo, string continent)
    {
        return repo.Where(c => c.Continent == continent);
    }
}

您還應該研究協方差與協方差,這可能有助於您首先了解為什么出現此問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM