Как использовать простой инжектор, репозиторий и контекст - сначала код

Я пытаюсь использовать Simple Injector для создания моего репозитория и использовать его на уровне бизнес-логики (также я хочу использовать метод PerWebRequest).

В слое DAL у меня есть:

public interface IRepository<T> where T : class
{
    void Add(T entity);
    void Delete(T entity);
    void Delete(int id);
    void Update(T entity);
    T GetById(int Id);
    IQueryable<T> All();
    IEnumerable<T> Find(Func<T, bool> predicate);
}

и:

public class EFRepository<T> : IRepository<T>, IDisposable where T : class
{
    #region Members
    protected DbContext Context { get; set; }
    protected DbSet<T> DbSet { get; set; }
    #endregion

    #region Constructors

    public EFRepository(DbContext dbContext)
    {
        if (dbContext == null)
            throw new ArgumentNullException("dbContext");
        Context = dbContext;
        DbSet = Context.Set<T>();
    }

и мой контекст:

public class PASContext : DbContext, IDbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<User> Users { get; set; }

    public PASContext()
        : base("PostAndSell")
    { }
}

Как вы видите, EFRepository имеет только один конструктор, который принимает один аргумент - это потому, что я хочу использовать Simple Injector для создания экземпляра контекста и передачи его в репозиторий во время его создания.

В BLL у меня есть класс ProductBLL, и я хочу получить все продукты в этом классе (с некоторым методом GetAll) из базы данных и передать его, скажем, в HomeController.

Мне действительно нужно, чтобы кто-то говорил мне об этом.

Я начал с установки правильных пакетов из nuger (Simple Injector и Simple Injector ASP.NET Integration)

также в моем файле global.asax.cs, в Application_Start() функции я добавил:

var container = new SimpleInjector.Container();

container.RegisterPerWebRequest<IRepository<Product>, EFRepository<Product>>();

но где я могу создать экземпляр Context? и как я могу получить доступ к нему на бизнес-уровне?

Ответ 1

Поскольку у вас, вероятно, будет много реализаций IReposotory<T> (для Product, Customer, Employee и т.д.), лучше сделать одну открытую общую регистрацию для IRepository<T> следующим образом:

container.Register(typeof(IRepository<>), typeof(EFRepository<>), Lifestyle.Scoped);

Если охваченный образ жизни определяется как:

container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

Эта регистрация гарантирует, что Simple Injector вернет EFRepository<Product>, каждый раз, когда запрашивается a IRepository<Product>, EFRepository<Customer> для IRepository<Customer> и т.д. и т.д.

Поскольку вы хотите, чтобы один и тот же экземпляр DbContext использовался во всех репозиториях в рамках одного и того же запроса, вы также должны зарегистрировать DbContext с помощью области Lifestyle:

container.Register<DbContext, PASContext>(Lifestyle.Scoped);

В BLL у меня есть класс ProductBLL, и я хочу получить все продукты из базы данных и передать ее, скажем, HomeController

В этом сценарии этот ProductBLL кажется мне бесполезной абстракцией. Если все, что он делает, это передача данных через, вы можете легко позволить вашему HomeController напрямую зависеть от IRepository<Product>.