Как сделать общий репозиторий с помощью инъекции зависимостей [закрыто]

Я настроил свой общий репозиторий следующим образом:

public interface IRepository<T> : IDisposable where T : Entity
{
    T GetById(int id);
}

public abstract class Repository<T> : IRepository<T> where T : Entity
{
    protected readonly SqlDbContext _context = new SqlDbContext();

    public T GetById(int id)
    {
        return _context.Set<T>().Find(id);
    }   
}

Чтобы включить внедрение зависимостей в моем приложении MVC, я также создаю интерфейс Product, поскольку подпись отличается. Это также относится и к другим репозиториям.

public interface IProductRepository : IRepository<Product>
{
    IEnumerable<Product> GetDiscountedProducts();
}

И реализация (обратите внимание на наследство)

public class ProductRepository : Repository<Product>, IProductRepository
{
    public IEnumerable<Product> GetDiscountedProducts()
    {
        return _context.Set<Product>().Where(x=>x)...
    }           
}

Наконец, хранилище внедряется в контроллер MVC с помощью единицы

public HomeController(IProductRepository repository)
{
}

Это только я или эта цепочка наследования здесь немного грязная? Есть ли способ улучшить этот дизайн?

7 голосов | спросил Fixer 19 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 19 Sep 2011 19:00:40 +0400 2011, 19:00:40

1 ответ


0

Я бы посоветовал избегать IProductRepository для этого конкретного случая (при простом добавлении одного и очень специфического метода) и улучшать оригинальный интерфейс IRepository как показано ниже:

public interface IRepository<TEntity> : IDisposable 
                 where TEntity : Entity 
{     
   TEntity GetById(int id); 
   IEnumerable<TEntity> List(IFilterCriteria criteria);
} 

, а затем реализовать

public sealed class ProductDiscountFilterCriteria : IFilterCriteria 
{
   // ...
}

но в таком случае вы должны определить некоторую логику для преобразования критериев в запрос, это может быть выражение LINQ, поскольку вы уже используете LINQ. Если такой подход к выражению креатии сложен для вашего случая - я бы предложил придерживаться предложенного вами подхода.

РЕДАКТИРОВАТЬ: IFilterCriteria просто Объект запроса Реализация шаблона

interface IFilterCriteria<TQuery>
{
   TQuery ToQuery();
}

public sealed class ProductDiscountFilterCriteria : IFilterCriteria<DynamicExpression>
{
  public decimal Discount { get; private set; }

  public DynamicExpression ToQuery()
  {
    // build expression for LINQ clause Where("Discount" > this.Discount)
  }
}

ИЛИ построитель необработанных критериев SQL:

public sealed class ProductDiscountFilterCriteria : IFilterCriteria<string>
{
  public decimal Discount { get; private set; }

  public string ToQuery()
  {
    // simplified
    return "WHERE Discount < " + this.Discount;
  }
}

Тогда вы сможете использовать его следующим образом:

var products = productRepository.List<Product>(
                             new DiscountFilterCriteria { Discount = 50 });

Динамические примеры LINQ и статьи:

ответил sll 19 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 19 Sep 2011 19:04:20 +0400 2011, 19:04:20

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132