1

リポジトリパターンの実装の下で試しました

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 と IRepository.All があいまいです。

これを解決するには?このようにリポジトリ パターンを使用するという私のアプローチの問題は何ですか?

4

2 に答える 2

1

推しはこのライン

return AdminRepository.All; // Here is error 

する必要があります

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

.All実装するインターフェイスを明示的に記述しないと宣言できなかったことにお気づきでしょう。これは、特定のクラスでは、同じ名前の 2 つのプロパティが異なる戻り値の型を持つことができないためです。

呼び出すときも同様です。呼び出しているプロパティを正確に伝える必要があります。これは、目的のインターフェイスにオブジェクトをキャストすることによって行われます。

とにかく、すべてのエンティティ タイプのリポジトリを実装することになるようです。IRepository<T>同じメカニズムから取得できるエンティティ タイプに対しては、1 回だけ実装する必要があります。

リポジトリを一部のクラスにのみ適用する場合は、たとえば、これらのクラスにインターフェイスのタグを付けることができます。としましょうIEntity

public interface IEntity
{
}

それから

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

次のように、db エンティティとしてタグ付けしたエンティティにのみ適用される db リポジトリを作成することもできます。

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();
    }
}
于 2013-03-15T10:01:58.337 に答える
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; }
  }

  ...
}
于 2013-03-16T15:52:04.537 に答える