Question

I'm trying to get work UnitOfWork, Ninject, and Repository pattern, For now I have this code:

 public class UnitOfWork : IUnitOfWork
{
    private readonly MyContext context;

    public IGenericRepository<User> UserRepository { get; set; }
    public IGenericRepository<EmailChangesByUser> EmailChangesByUserRepository { get; set; }
    public IGenericRepository<PasswordChangesByUser> PasswordChangesByUserRepository { get; set; }
    public IGenericRepository<MyUserDataChanges> MyUserDataChangesByUserRepository { get; set; }
    public IGeoRepository GeoRepository { get; set; }
    public IFileManager FileManager { get; set; }

    public UnitOfWork(MyContext cont, IGenericRepository<User> userRepo,
        IGenericRepository<EmailChangesByUser> emailChangesByUserRepo,
        IGenericRepository<PasswordChangesByUser> passwordChangesByUserRepo,
        IGenericRepository<MyUserDataChanges> myUserDataChangesByUserRepo,
        IFileManager fileUploader, IGeoRepository geoRepo)
    { ... }
}

All is working ok. But I can add plus dependencies and so the constructor will be very fat. So I'm trying to do the same in this other way (sumarized code):

public class UnitOfWork : IUnitOfWork
{
    private readonly MyContext _context;
    private Hashtable _repositories;

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

    public IRepository<TEntity> Repository<TEntity>() where TEntity : IEntity
    {
        if (_repositories == null)
        {
            _repositories = new Hashtable();
        }

        var type = typeof(TEntity).Name;

        if (_repositories.ContainsKey(type))
        {
            return (IRepository<TEntity>)_repositories[type];
        }

         _repositories.Add(...) // HERE IS MY PROBLEM, ANY WAY TO INJECT HERE REPOS

        return (IRepository<TEntity>)_repositories[type];
    }
}

I don't know if I can explain myself correct!

Was it helpful?

Solution

You could approach this differently. Since both repositories and the unit of work is specified in an abstract way (with interfaces), your concrete implementation of the unit of work should create concrete instances of repositories:

public class EntityFrameworkUnitOfWork : IUnitOfWork
{
  private readonly MyContext context;

  private IGenericRepository<User> _userRepository 
  public IGenericRepository<User> UserRepository 
  { 
      get
      {
          if ( _userRepository == null )
             _userRepository = new EntityFrameworkUserRepository( this.context );
          return _userRepository;
      }
  }

  public UnitOfWork(MyContext cont)
  { 
      this.cotnext = cont;
  }
}

public class AnotherConcreteUnitOfWork : IUnitOfWork
{
  private readonly Something some;
  private readonly Another dependency;

  private IGenericRepository<User> _userRepository 
  public IGenericRepository<User> UserRepository 
  { 
      get
      {
          if ( _userRepository == null )
             _userRepository = new AnotherConcreteUserRepository( some, dependency );
          return _userRepository;
      }
  }

  public UnitOfWork(Something some, Another dependency)
  { 
      this.some = some;
      this.dependency = dependency;
  }
}

so that when you switch between implementations, you specify only the concrete type for the unit of work:

kernel.Bind<IUnitOfWork>().To<EntityFrameworkUnitOfWork>();

or

kernel.Bind<IUnitOfWork>().To<AnotherConcreteUnitOfWork>();

Note that having a concrete unit of work for concrete set of repositories makes it easier to deal with external dependencies you have to inject first to the unit of work and from there, to repositories (in the example above, there entity framework unit of work depends on the dbcontext while the other unit of work depends on other objects).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top