Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic Unit Of Work

I have implemented EntityFramework pattern along with Repository and Unit Of Work. The implementation is similar to Code Project Repository Example, however I need an enhancement for the Unit Of Work.

The unit of work

public class GenericUnitOfWork : IDisposable
{
    // Initialization code

    public Dictionary<Type, object> repositories = new Dictionary<Type, object>();

    public IRepository<T> Repository<T>() where T : class
    {
        if (repositories.Keys.Contains(typeof(T)) == true)
        {
            return repositories[typeof(T)] as IRepository<T>
        }
        IRepository<T> repo = new Repository<T>(entities);
        repositories.Add(typeof(T), repo);
        return repo;
    }

    // other methods
}

The above UoW is quiet generalized and it targets the parent Repository class always. I have another entity, for example student, which has its own repository extending the Repository class. The student specific repository has a method "GetStudentMarks()". Now I cannot use the general Unit Of Work class since it always points to the parent Repository.

How to implement a general Unit Of Work to handle such situations? Thanks in advance.

like image 553
Vyas Rao Avatar asked Feb 06 '23 05:02

Vyas Rao


1 Answers

Generic UnitOfWork !!! You've implemented the wrong unit of work

See This Code:

using System.Data.Entity;
using System;


namespace EF_Sample07.DataLayer.Context
{
 public interface IUnitOfWork
{
    IDbSet<TEntity> Set<TEntity>() where TEntity : class;
    int SaveChanges();
   }
 }

Why Use UnitOfWork?

Because:

  • Better performance
  • Concurrency issues
  • The correct use of transactions

See Example :

Category

   public class Category
{
    public int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Title { get; set; }


    public virtual ICollection<Product> Products { get; set; }
}

Product

    public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }


    [ForeignKey("CategoryId")]
    public virtual Category Category { get; set; }
    public int CategoryId { get; set; }
}

UnitOfWork

  public interface IUnitOfWork
{
    IDbSet<TEntity> Set<TEntity>() where TEntity : class;
    int SaveChanges();
}

DbContext

    public class Sample07Context : DbContext, IUnitOfWork
{
    public DbSet<Category> Categories { set; get; }
    public DbSet<Product> Products { set; get; }


    #region IUnitOfWork Members
    public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
    {
        return base.Set<TEntity>();
    }
    public int SaveAllChanges()
    {
        return base.SaveChanges();
    }
    #endregion
}
like image 135
Soheil Alizadeh Avatar answered Feb 24 '23 04:02

Soheil Alizadeh