我当前的结构如下:
public class CustomerRepository
{
// ..
public virtual Customer LoadCustomer()
{
// ...
}
}
public class OracleCustomerRepository : CustomerRepository
{
private OracleConnection oracleConnection;
public OracleCustomerRepository()
: base(){
if(this.EnsureIsConnected()){
// ...
}
}
private bool EnsureIsConnected(){
// ..
}
public override Customer LoadCustomer(){
// ..
}
}
效果很好,除了以下事实:-对于每个OracleRepository
-我必须再次编写方法EnsureIsConnected
,我必须再次声明已归档的OracleConnection
等。
我想抽象一下。我的第一个想法是使用Interface
,但这不能解决重复代码的问题。我的第二个想法是将基类CustomerRepository
用作另一个新基类OracleRepository<T>
的通用类型,该基类随后定义了公共例程。
问题是:据我所知,无法override
这种通用类型的virtual
方法,例如CustomerRepository
。
我就是这么认为的。
public class OracleRepository<T> where T : class{
public OracleRepository(){
this.EnsureIsConnected());
}
protected OracleConnection oracleConnection;
protected EnsureIsConnected(){
// ...
}
}
public class OracleCustomerRepository : OracleRepository<CustomerRepository>{
// ..
// this is not possible, defined in CustomerRepository
public override Customer LostCustomer(){
}
}
注意:CustomerRepository
不是我唯一的存储库。这主要是我试图找到更好的解决方案的原因。
关于如何处理此问题的任何建议?
答案 0 :(得分:2)
我的第一个想法是您的抽象似乎有点泄漏。 我通常要做的是使用以下方法创建与数据库引擎交互的界面:
public interface IPersistence
{
void ExecuteOperation(string prodecureName, Dictionary<string, object> parameters);
T ExecuteSingle(string procedureName, Dictionary<string, object> parameters, Func<IDataReader, T> rowReader);
List<T> ExecuteMultirow(string procedureName, Dictionary<string, object> parameters,
Func<IDataReader, T> rowReader);
}
然后在存储库中将其作为依赖项,并从IoC容器中确定要使用的实现。 因此,在您的代码中您将拥有:
public class CustomerRepository
{
private readonly IPersistence persistence;
public CustomerRepository(IPersistence persistence)
{
this.persistence = persistence;
}
public virtual Customer LoadCustomer()
{
// preparation code
return this.persistence.ExecuteSingle("some procedure", parameters, r => new Customer((int)r["Id"], (string)r["DisplayName"]));
}
}
答案 1 :(得分:1)
可以这样做吗?还是这不是您想要的?
public abstract class CustomerRepository<T>
{
protected OracleConnection oracleConnection;
protected CustomerRepository() : base(){
if(EnsureIsConnected()){
// ...
}
}
protected bool EnsureIsConnected()
{
return true;
}
public abstract T Load();
}
public class OracleCustomerRepository : CustomerRepository<Customer>
{
public override Customer Load(){
return new Customer();
}
}