HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Generic Repository, UnitOfWork and IOC container

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
genericioccontainerandrepositoryunitofwork

Problem

I am stuck to define a generic repository with AutoFac IOC container. I am keeping thing very simple and only showing relevant information.

BaseEntity

public abstract class BaseEntity
{
    public int Id { get; set; }
}


IRepository

public interface IRepository where TEntity : BaseEntity
{
    List GetAll();
    void Insert(TEntity entity);
    void Update(TEntity entity);
    void Delete(TEntity entity);
}


IUnitOfWork

public interface IUnitOfWork : IDisposable
{
    int SaveChanges();
    void Dispose(bool disposing);
    IRepository Repository() where TEntity : BaseEntity;
}


IService

public interface IService
{
    IUnitOfWork UnitOfWork { get; }
}


IService

public interface IService : IService where TEntity : BaseEntity
{
    List GetAll();
    TEntity GetById(int id);
    void Add(TEntity entity);
    void Update(TEntity entity);
    void Delete(TEntity entity);
}


UnitOfWork

public class UnitOfWork : IUnitOfWork
{

    private readonly IEntitiesContext _context;
    private bool _disposed;
    private ObjectContext _objectContext;
    private Hashtable _repositories;
    private DbTransaction _transaction;

    public UnitOfWork(IEntitiesContext context)
    {
        _context = context;
    }

    public int SaveChanges()
    {
        return _context.SaveChanges();
    }

    public IRepository Repository() where TEntity : BaseEntity
    {
        if (_repositories == null)
        {
            _repositories = new Hashtable();
        }
        var type = typeof(TEntity).Name;
        if (_repositories.ContainsKey(type))
        {
            return (IRepository)_repositories[type];
        }
        var repositoryType = typeof(EntityRepository<>);
        _repositories.Add(type, Activator.CreateInstance(repositoryType.MakeGenericType(typeof(TEntity)), _context));
        return (IRepository)_repositories[type];
    }
}


Service

```
public class Service : IService where TEntity : Bas

Solution

First, I would caution against using the generic repository + unit of work pattern that was super trendy a few years ago because it has problems not unlike the problems you're facing (along with problems stemming from the fact that EF crosses traditional DAL/Domain/BL boundaries). Simply put, I would not use repositories with EF unless absolutely necessary, and if I had to, I would not use the generic repository pattern.

If you're hell-bent on using this pattern, then you will need to understand the origins of the problem you're facing. Because you have a generic type being returned by your UnitOfWork "factory," you aren't able to instantiate it during your bootstrapping, you are being forced to to instantiate it on-demand at runtime, resolving using the type you're using in your UnitOfWork method call.

If you are okay with using the same repository instance for all of your resolutions, then just make your objects require Repository in your object constructors or properties with public setters, then use RegisterGeneric(). You can see how that is used here. This bypasses the entire "at runtime" requirement.

If you want to maintain the pattern of fetching a repository using a method, then you need to treat your UnitOfWork class as a factory and use dynamic instantation.

Context

StackExchange Code Review Q#45322, answer score: 2

Revisions (0)

No revisions yet.