解决基于接口的方法中的歧义

时间:2013-03-15 09:51:18

标签: c# asp.net oop design-patterns repository-pattern

我尝试了下面的Repository Pattern实现

interface IRepository<T>
{
    IQueryable<T> All { get; }
    T Find(object id);
    void Insert(T model); 
}

然后我在下面定义了IAdminRepository

interface IAdminRepository : IRpository<Role>, IRepository<User>
{
}

public class AdminRepository:IAdminRepository
{
    IQueryable<User> IRepository<User>.All
    {
        get { throw new NotImplementedException(); }
    }

    User IRepository<User>.Find(object id)
    {
        throw new NotImplementedException();
    }

    void IRepository<User>.Insert(User model)
    {
        throw new NotImplementedException();
    }

    IQueryable<Role> IRepository<Role>.All
    {
        get { throw new NotImplementedException(); }
    }

    Role IRepository<Role>.Find(object id)
    {
        throw new NotImplementedException();
    }

    void IRepository<Role>.Insert(Role model)
    {
        throw new NotImplementedException();
    }
}

在我的业务层中,我使用基于接口的呼叫。

public interface IAdminService
{
    bool CreateUser(User user);        
    List<User> GetAllUsers();
}

public class AdminService : IAdminService
{
    private readonly IAdminRepository AdminRepository;

    public AdminService(IAdminRepository _adminRepository)
    {
        AdminRepository = _adminRepository;
    }

    public bool CreateUser(User user)
    {
        AdminRepository.Insert(user);
        return true;
    }

    public List<User> GetAllUsers()
    {
        return AdminRepository.All; // Here is error 
    }
}
  

错误:IRepository.All&amp;   IRepository.All。

如何解决这个问题?我以这种方式使用Repository Pattern的方法有什么问题?

2 个答案:

答案 0 :(得分:1)

我想这一行

return AdminRepository.All; // Here is error 

应该是

return ((IRepository<User>)AdminRepository).All.ToList();

您可能已经注意到,如果没有明确地编写您正在实现的接口,您将无法声明.All。这是因为,对于给定的类,具有相同名称的两个属性不能具有不同的返回类型。

调用时也一样。您必须确切地告诉您要调用的属性。这是通过将对象转换为所需的接口来完成的。

无论如何,您似乎最终会为所有实体类型实现存储库。您应该只为可以从同一机制检索的实体类型实现IRepository<T>一次。

如果您希望存储库仅应用于某些类,则可以使用接口标记这些类。我们说IEntity

public interface IEntity
{
}

然后

public interface IRepository<T> where T:IEntity
{
    IQueryable<T> All { get; }
    T Find(object id);
    void Insert(T model);
}

您甚至可以拥有仅适用于您已标记为数据库实体的实体的数据库存储库,如下所示:

public interface IDbEntity: IEntity
{
}


public class DbRepository<T> : IRepository<T> where T:IDbEntity
{
    public IQueryable<T> All { get; private set; }
    public T Find(object id)
    {
        throw new NotImplementedException();
    }

    public void Insert(T model)
    {
        throw new NotImplementedException();
    }
}

答案 1 :(得分:1)

消除歧义歧义的一种简单方法是创建别名方法:

public class AdminRepository : IAdminRepository {

  public IQueryable<User> AllUsers {
    get { throw new NotImplementedException(); }
  }

  public IQueryable<Role> AllRoles {
    get { throw new NotImplementedException(); }
  }

  IQueryable<User> IRepository<User>.All {
    get { return AllUsers; }
  }

  IQueryable<Role> IRepository<Role>.All {
    get { return AllRoles; }
  }

  ...
}