如何使用简单的注入器,存储库和上下文 - 代码优先

jon*_*y89 11 c# asp.net-mvc repository inversion-of-control simple-injector

我正在尝试使用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);
}
Run Code Online (Sandbox Code Playgroud)

并且:

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>();
    }
Run Code Online (Sandbox Code Playgroud)

和我的背景:

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

    public PASContext()
        : base("PostAndSell")
    { }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的EFRepository,只有一个构造函数接受一个参数 - 这是因为我想使用Simple Injector创建上下文的实例,并在创建时将其传递给存储库.

在BLL中我有一个类ProductBLL,我想从数据库中获取该类中的所有产品(使用一些GetAll方法)并传递它,让我们说到HomeController.

我真的需要有人来跟我说话.

我首先从nuger安装正确的软件包(Simple Injector和Simple Injector ASP.NET Integration)

同样在我的global.asax.cs文件中,在Application_Start()函数I下添加了:

var container = new SimpleInjector.Container();

container.RegisterPerWebRequest<IRepository<Product>, EFRepository<Product>>();
Run Code Online (Sandbox Code Playgroud)

但是我在哪里创建Context实例?以及如何在业务层中访问它?

Ste*_*ven 16

由于您可能会有许多IReposotory<T>实现(对于产品,客户,员工等),因此最好如下所示进行单一的开放式通用注册IRepository<T>:

container.Register(typeof(IRepository<>), typeof(EFRepository<>), Lifestyle.Scoped);
Run Code Online (Sandbox Code Playgroud)

范围生活方式定义为:

container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
Run Code Online (Sandbox Code Playgroud)

该注册确保简单的喷油器将返回EFRepository<Product>,每次IRepository<Product>请求,一EFRepository<Customer>对IRepository<Customer>,等等,等等.

由于您希望在同一DbContext请求中的所有存储库上使用相同的实例,因此您还应该DbContext使用范围生活方式注册:

container.Register<DbContext, PASContext>(Lifestyle.Scoped);
Run Code Online (Sandbox Code Playgroud)

在BLL中我有一个ProductBLL类,我想从数据库中获取所有产品并将其传递给,让我们说HomeController

在那种情况下,这ProductBLL对我来说似乎是一种无用的抽象.如果只是传递数据,您可以轻松地直接HomeController依赖IRepository<Product>.

  • 解析类型时,Simple Injector会将依赖项注入该类型的构造函数中.如果您的HomeController依赖于BBLProducts,并且您解析了HomeController,Simple Injector将为您创建BBLProducts.如果BBLProducts依赖于IRepository <Product>,Simple Injector将为您注入一个EFRepository <Product>到该BBLProducts中.Simple Injector将为您构建相关对象的完整图表.您只需解析根对象,在MVC的情况下,将为您解析此根对象(控制器). (2认同)