Как использовать простой инжектор, репозиторий и контекст - сначала код
Я пытаюсь использовать 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>
.