2013-11-09 3 views
2

Я не уверен, что то, что я хотел бы сделать, возможно, так как я ничего не нашел в Google и после примерно 30 минут интенсивного поиска я решил напрямую спросить.Внедрение универсального типа в репозитории

Я definded простого интерфейса для моего репозитория

public interface IRepository<TEntity> : IDisposable 
{ 
    TEntity GetById(object id); 
    List<TEntity> GetAll(); 
} 

Теперь я хочу, чтобы реализовать свой первый репозиторий и как это работает

public class ContentRepository : IRepository<ContentPages> 
{ 
    private readonly Context _db = new Context(); 

    public ContentPages GetById(object id) 
    { 
     var result = _db.ContentPages.Find(id); 
     return result; 
    } 

    public List<ContentPages> GetAll() 
    { 
     return _db.ContentPages.ToList(); 
    } 

    public void Dispose() 
    { 
     _db.Dispose(); 
    } 
} 

Это работает нормально, но когда я впрыснуть свой репозиторий мой контроллер mvc в качестве типа параметра принимает IRepository<ContentPages>, и я просто хочу, чтобы он принял IRepository.

Я попытался переместить общий тип к функциям себя как этого

public interface IRepository : IDisposable 
    { 
     TEntity GetById<TEntity>(object id); 
     List<TEntity> GetAll<TEntity>(); 
    } 
} 

Когда я делаю это я не знаю, как определить свой общий тип TEntity в реализации

Итак, в заключении Я хочу, чтобы мои использовать интерфейс без speficing типа поэтому он получает тип от реального объекта, как этого

public constructor1(IRepository ContentRepository){} 

следующего контроллер получает т его конструктор

public constructor2(IRepository BlogRepository){} 

и так далее

Я надеюсь, что я мог бы описать мою проблему достаточно близко к у ребят понять :)

ответ

0

В конкретной реализации IRepository класса вы можете определить тип TEntity следующим образом.

public TEntity GetById<TEntity>(object id) where TEntity:class 
    { 
    // Implimetation 
    } 

Но здесь, в соответствии с шаблоном хранилища, лучше использовать следующее.

public interface IRepository<TEntity>: IDisposable where TEntity : class 
+0

Когда я использую свой первый пример и осуществить следующим образом: возврата _db.ContentPages.Find (ID); Я получаю cant конвертировать ContentPages в TEntity Я не могу сказать, что Tentity: ContentPages, потому что он нарушает интерфейс – Marvin

0

попробовать такой вариант:

public interface IRepository<TEntity> where TEntity : class 
{ 
    TEntity Find(params object[] keyValues); 

    // ... 
} 

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class 
{ 
    private readonly IDbSet<TEntity> _dbSet; 

    public Repository(IDbContext context) 
    { 
     _dbSet = context.Set<TEntity>(); 
    } 

    public virtual TEntity Find(params object[] keyValues) 
    { 
     return _dbSet.Find(keyValues); 
    } 

    // ... 
} 

Пример использования:

IRepository<ApplicationUser> repository = new Repository<ApplicationUser>(new ApplicationDbContext()); 
ApplicationUser applicationUser = repository.Find("key"); 

Кроме того, есть лучшее решение - вы можете использовать шаблон UnitOfWork. Проверьте this implementation on codeplex. Это действительно здорово.

Пример:

public class DatabasesController : Controller 
{ 
    private UnitOfWork _unitOfWork; 
    private WebContext _context; 

    public DatabasesController() 
    { 
     _context = new WebContext(); 
     _unitOfWork = new UnitOfWork(_context); 
    } 

    // 
    // GET: /Databases/ 

    public ViewResult Index() 
    { 
     List<Database> databases = 
      _unitOfWork 
      .Repository<Database>() 
      .Query() 
      .Include(database => database.FileEntitiesInfo) 
      .Get() 
      .ToList(); 
     _unitOfWork.Save(); 
     return View(databases); 
    } 
} 
Смежные вопросы