我怎样才能以简单的方式注入存储库?

时间:2014-04-23 15:36:13

标签: entity-framework dependency-injection ninject asp.net-mvc-5 unit-of-work

我正在尝试使用UnitOfWork,Ninject和Repository模式,现在我有了这段代码:

 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)
    { ... }
}

一切正常。但我可以添加加依赖项,因此构造函数将非常胖。所以我试图用另一种方式做同样的事情(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];
    }
}

我不知道我是否可以解释自己是正确的!

1 个答案:

答案 0 :(得分:1)

你可以采用不同的方法。由于两个存储库和工作单元都是以抽象方式(带接口)指定的,因此工作单元的具体实现应创建存储库的具体实例:

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;
  }
}

因此,当您在实现之间切换时,只需指定工作单元的具体类型:

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

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

请注意,为具体的存储库集合建立一个具体的工作单元,可以更轻松地处理您必须首先注入工作单元并从那里注入存储库的外部依赖项(在上面的示例中,有实体框架单元)工作依赖于dbcontext而其他工作单元依赖于其他对象。)