Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Simple injector, Repository and Context - code first

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 ) .

In the DAL layer i have :

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);
}

and :

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>();
    }

and my context :

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

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

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 .

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 .

I started by installing the right packages from the nuger (Simple Injector and Simple Injector ASP.NET Integration)

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>>();

but where do i create the Context instance ? and how can i access it in the business layer ?

like image 713
jony89 Avatar asked Dec 15 '13 12:12

jony89


People also ask

Is simple Injector safe?

Simple Injector is thread-safe and its lock-free design allows it to scale linearly with the number of available processors and threads.

Why use unitofwork?

The unit of work class serves one purpose: to make sure that when you use multiple repositories, they share a single database context. That way, when a unit of work is complete you can call the SaveChanges method on that instance of the context and be assured that all related changes will be coordinated.

How do you install a simple Injector?

Download Simple Injector and Adding Reference To download from NuGet just right-click on your application then select Manage NuGet Packages. A new dialog will pop up. That dialog is a search box; enter “Simple Injector” into it. Install the first result Simple Injector Version 2.7.

What is repository in entity framework?

The Repository Pattern allows us to create an abstraction layer between the data access layer and the business logic layer of an application. So, this Data Access Pattern offers a more loosely coupled approach to data access.


1 Answers

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();

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.

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);

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

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.

like image 146
Steven Avatar answered Sep 20 '22 02:09

Steven