best practice to implement repository pattern and

2020-07-28 11:25发布

问题:

I am working on implementing Repository Pattern and UnitOfWork from last few days, which I have completed to upto good extend, I believe. I am sure there are plenty of ways to implement that but what I am interesting to find best approach for that.

I am taking very simple example coded in ASP.NET MVC 5 using visual studio 2013. my main focus of question is implementation of UnitOfWork. is it advisable to use multiple UnitOfWorks for each business concerns implementing repository functions in private method and giving away public functions for controller to use????

I have function table (SQL Server) in the controller class via generic repository. I have IGenericRepository which has IQueryable one function, I have GenericRepository class where i am implementing this interface. I got FunctionContext which is inherited from baseContext. The reason i have baseContext so all the dbcontexts can use one path to hit database but same time keep number of table limited to business need.

now in my approach;

  1. One BaseContext : DbContext
  2. multiple DbContext, bundling all required table to individual business concern that extend BaseContext
  3. Generic Repository Interface (CRUD)
  4. Generic Repository Implementation class
  5. specific Repository class, extending Generic Reposirtory in case require more function on top of CRUD operations.
  6. Individual UnitOfWork --> taking to required repository/ repositories in private method and provide public method only for using functions
  7. Controller call require UnitOfWork to use public methods.

in following program, all i am getting list of function title and passing to controller to print

Generic Repository Interface

 public interface IGenericRepository<TEntity> : IDisposable
{
    IQueryable<TEntity> GetAll(); 

}

Generic Repository

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
    protected DbSet<TEntity> _DbSet;
    private readonly DbContext _dbContext;

    public GenericRepository()
    {

    }

    public GenericRepository(DbContext dbContext)
    {
        this._dbContext = dbContext;
        _DbSet = _dbContext.Set<TEntity>();
    }



    public IQueryable<TEntity> GetAll()
    {
        return _DbSet;
    }


    public void Dispose()
    {

    }
}

BaseContext

 public class BaseContext<TContext> : DbContext where TContext : DbContext
{
    static BaseContext()
    {
        Database.SetInitializer<TContext>(null);
    }

    protected BaseContext()
        : base("name = ApplicationDbConnection")
    { }
}

FunctionContext

 public class FunctionsContext : BaseContext<FunctionsContext>
{
    public DbSet<App_Functions> Functions { get; set; }
}

Function Mapping class

[Table("Functions")]
public class App_Functions
{
     public App_Functions()
    {
    }

    [Key]
    public int Function_ID { get; set; }

    [StringLength(50)]
    [Required]
    public string Title { get; set; }

    public int Hierarchy_level { get; set; }
}

Function Domain class

 public class Functions
{
    public Functions()
    {

    }

    public int Function_ID { get; set; }
    public string Title { get; set; }
    public int Hierarchy_level { get; set; }
}

Function_UnitOfWork

public class Function_UnitOfWork
{
   private GenericRepository<App_Functions> _function_Repository = new GenericRepository<App_Functions>(new FunctionsContext());

   public Function_UnitOfWork()
   {

   }

   private List<Functions> getAllFunctionsFromRepository()
   {
       List<Functions> query = new List<Functions>();

       query = _function_Repository.GetAll().Select(x => new Functions
       {
           Function_ID = x.Function_ID,
           Title = x.Title,
           Hierarchy_level = x.Hierarchy_level
       }).ToList();

       return query; 
   }

   public List<Functions>GetAllFunctions()
   {
       return getAllFunctionsFromRepository();
   }



}

Controller class

public class HomeController : Controller
{
    public ActionResult Index()
    {
         Function_UnitOfWork UOF = new Function_UnitOfWork();

       var a1 = UOF.GetAllFunctions();

        foreach(var item in a1)
        {
            var b1 = item.Title;
        }


        return View();
    }
}

回答1:

While it is opinion based, just the name of of Unit Of Work pattern suggest limited timespan of the object. So the use of it in controller should be something like

public ActionResult Index()
{
   using(var UOF = new Function_UnitOfWork()) {

     var a1 = UOF.GetAllFunctions();

     foreach(var item in a1)
     {
       var b1 = item.Title;
     }
   }

    return View();
}

Also one approach we use is (in short)

public class DataObject { }

public class Repo: IRepo<T> where T: DataObject

public class RepoController<T> : Controller where T: DataObject {
   protected IRepo<T> Repo;
}

So controllers will be generic and will have field for particular repo

You will use some dependency injection tool, like ninject or mef to bound controllers with repos behind the scene.