如何使用简单注入器,存储库和上下文-代码优先 [英] How to use Simple injector, Repository and Context - code first
问题描述
我正在尝试使用Simple Injector创建我的存储库并在业务逻辑层中使用它(我也想使用PerWebRequest方法).
I'm trying to use Simple Injector to create my repository and use it in the Business logic layer ( also i want to use PerWebRequest method ) .
在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创建上下文的实例,并将其在创建时传递给存储库.
As you can see EFRepository
has only one constructor that takes one argument - this is because i want to use Simple Injector to create an instance of the context and pass it to the repository while it is created .
在BLL中,我有一个类ProductBLL
,我想从数据库中获取该类中的所有产品(使用某些GetAll方法)并将其传递,比如说HomeController.
In the BLL i have a class ProductBLL
and i want to get all products in that class (with some GetAll method) from the database and pass it, lets say to HomeController .
我真的需要有人通过这个与我交谈.
I really need someone to talk me through this .
我首先从nuger安装了正确的软件包(简单注入器和简单注入器ASP.NET集成)
I started by installing the right packages from the nuger (Simple Injector and Simple Injector ASP.NET Integration)
也在我的global.asax.cs文件中的Application_Start()
函数下添加了:
also in my global.asax.cs file, under Application_Start()
function I`ve added :
var container = new SimpleInjector.Container();
container.RegisterPerWebRequest<IRepository<Product>, EFRepository<Product>>();
但是我在哪里创建Context实例?以及如何在业务层中访问它?
but where do i create the Context instance ? and how can i access it in the business layer ?
推荐答案
由于您可能会有许多IReposotory<T>
实现(针对产品,客户,员工等),因此最好对IRepository<T>
进行一次开放的通用注册像这样:
Since you will probably have many IReposotory<T>
implementations (for Product, Customer, Employee, etc), it's better make a single open generic registration for IRepository<T>
like this:
container.Register(typeof(IRepository<>), typeof(EFRepository<>), Lifestyle.Scoped);
其中范围内的生活方式定义为:
Where the scoped lifestyle is defined as:
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
此注册可确保每次请求IRepository<Product>
时,Simple Injector都将返回EFRepository<Product>
,对于IRepository<Customer>
而言,将返回EFRepository<Customer>
,依此类推,等等.
This registration ensures that Simple Injector will return a EFRepository<Product>
, every time a IRepository<Product>
is requested, an EFRepository<Customer>
for IRepository<Customer>
, and so on, and so on.
由于要在同一请求中的所有存储库上使用相同的DbContext
实例,因此还应该在范围为Lifestyle的生活方式中注册DbContext
:
Since you want the same DbContext
instance to be used over all repositories within the same request, you should also register the DbContext
with the scoped Lifestyle:
container.Register<DbContext, PASContext>(Lifestyle.Scoped);
在BLL中,我有一个ProductBLL类,我想获取所有产品 从数据库并将其传递给,比如说HomeController
In the BLL i have a class ProductBLL and i want to get all products from the database and pass it to, lets say HomeController
在那种情况下,这个ProductBLL
对我来说似乎是一个无用的抽象.如果它所做的只是传递数据,则可以轻松地使HomeController
直接依赖于IRepository<Product>
.
In that scenario, this ProductBLL
seems like a useless abstraction to me. If all it does is passing data through, you can as easily let your HomeController
depend on IRepository<Product>
directly.
这篇关于如何使用简单注入器,存储库和上下文-代码优先的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!