patterncsharpMinor
Generic Repository, UnitOfWork and IOC container
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.
```
public class Service : IService where TEntity : Bas
BaseEntitypublic abstract class BaseEntity
{
public int Id { get; set; }
}IRepositorypublic 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;
}IServicepublic 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
If you are okay with using the same repository instance for all of your resolutions, then just make your objects require
If you want to maintain the pattern of fetching a repository using a method, then you need to treat your
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.