简体   繁体   中英

Unit of Work Casting issue in Repository pattern

Updated: I am trying to get user repository using following code with repository pattern. I am getting the run time casting exception

"Unable to cast object of type 'Bidstruct.Repository.Repository`1[Bidstruct.Entities.User]' to type 'Bidstruct.Repository.IUserRepository'" at this line

userRepo = (IUserRepository)authUnitOfWork.Repository();

    public class UserController : Controller
    {
           private readonly IUnitOfWork authUnitOfWork;
           private readonly IUserRepository userRepo;

            public UserController(
                [Dependency("BidstructAuthUnitOfWork")] IUnitOfWork authUoW,
            {
                 authUnitOfWork = authUoW;
                 userRepo = (IUserRepository)authUnitOfWork.Repository<User>();
            }
      }

     public interface IUnitOfWork
     {
          IRepository<T> Repository<T>() where T : class;
     }

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


       public IRepository<T> Repository<T>() where T : class
       {
          if (_repositories == null)
            _repositories = new Hashtable();

         var type = typeof (T).Name;
         if (!_repositories.ContainsKey(type))
         {
            var repositoryType = typeof (Repository<>);

            var repositoryInstance = 
                Activator.CreateInstance(repositoryType
                        .MakeGenericType(typeof (T)), _context);

            _repositories.Add(type, repositoryInstance);
         }

        return (IRepository<T>) _repositories[type];
       }
    }
    // User Repository Interface
    public interface IUserRepository : IRepository<User>
    {
    }
    public class UserRepository : Repository<User>, IUserRepository
    { 
    }

Any idea what i am doing wrong?

That is simple. The implementation of authUnitOfWork.Repository<User>() returns instance of class that doesn't implement IUserRepository , but still implements IRepository<User> . There is nothing that stops this method from returning IWhateverIWantRepository as long as it implements IRepository<User> .

You could either change your design so this is enforced or enforce that all repositories implement I{SomeEntity}Repository instead of IRepository<SomeEntity> . Either of those would be pretty complex.

Error in your code is on those lines:

var repositoryType = typeof (Repository<>);
var repositoryInstance = Activator.CreateInstance(repositoryType.MakeGenericType(typeof (T)), _context);

This creates instance of Repository<User> and not UserRepository . The runtime doesn't know you actually want some class that is related, but different to Repository<T> . To fix it you either need to pass it the UserRepository type or register it beforehand. You cannot expect the runtime to do it for you.

try below thing u should put user as IRepository I guess..

private readonly IRepository<User> userRepo;
private readonly IRepository<User> roleRepo;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM