次のクラスとインターフェイスで構成される基本的な設計があります。
IRepository<TEntity>
インターフェース、Repository<TEntity>
基本クラス、- そして具体的な
TenantRepository
クラス。
問題"
インターフェイスによって継承されたものはすべて、定義によりパブリック アクセスを持っているため、Add
メソッド (基本クラス)を呼び出すことができます。
_tenantRepository.Add(new Tenant { Name = "blah" } );
Create
メソッドを呼び出す必要がある間TenantRepository
_tenantRepository.Create("blah");
質問
クライアントコードがメソッドにアクセスできないようにメソッドを保護されたものとして定義できればいいのですがAdd
、それはインターフェイスで定義されたメソッドであり、パブリックアクセスが必要であるという単純な事実のために許可されていません。
あるいは、具象クラスの実装を実際にオーバーライドできるように、メソッドに同じ名前を付けることもできます。これにより、クライアント コードが を直接呼び出すことができなくなりますRepository.Add
。しかし、場合によっては、クライアント コードが基本クラスで定義されたメソッドを呼び出さないようにしたいことがあります。
別の方法として、次のように書くこともできます。
new protected void Add(Tenant tenant)
{
}
しかし、それは私を震えさせます(そして、メソッド名のリファクタリングを開始するとすぐに壊れます)。
これを達成するためのより良い方法はありますか?
参考としていくつかのコード スニペット:
インターフェース:
public interface IRepository<TEntity> : IDisposable where TEntity : IEntity
{
IQueryable<TEntity> GetAll();
void Delete(TEntity entity);
void Add(TEntity entity);
}
基本クラスのごく一部:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity
{
protected IDbContext Context;
public Repository(IDbContext context)
{
Context = context;
}
public void Add(TEntity entity)
{
DbSet.Add(entity);
}
// Left out other, for this question irrelevant, method implementations
}
そして最後にTenantRepository
public class TenantRepository : Repository<Tenant>
{
public TenantRepository(IDbContext context)
: base(context)
{
}
public Tenant Create(string tenantName)
{
var tenant = new Tenant
{
Name = tenantName,
Guid = Guid.NewGuid().ToString()
};
if (Exists(tenant.Name))
{
throw new TenantAlreadyExistsException(tenant.Name);
}
Add(tenant);
return tenant;
}
// Left out other, for this question irrelevant, method implementations
}