我的数据访问层给自己带来了一点问题。在此特定实例中,我有一个表,其中可能包含 5 种类型的“实体”。这些基本上是公司、客户、站点等。类型由表中的 PositionTypeId 决定。它们都在同一个表中,因为它们都具有相同的数据结构; PositionId、描述和代码。
我有一个主要的抽象类如下:
public abstract class PositionProvider<T> : DalProvider<T>, IDalProvider where T : IPositionEntity
{
public static PositionProvider<T> Instance
{
get
{
if (_instance == null)
{
// Create an instance based on the current database type
}
return _instance;
}
}
private static PositionProvider<T> _instance;
public PositionType PositionType
{
get
{
return _positionType;
}
}
private PositionType _positionType;
// Gets a list of entities based on the PositionType enum's value.
public abstract List<T> GetList();
internal void SetPositionType(RP_PositionType positionType)
{
_positionType = positionType;
}
}
然后我希望能够将所有通用代码放入一个基于 SQL 或 Oracle 的继承类中。这是我的 SQL 实现:
public class SqlPositionProvider<T> : PositionProvider<T> where T : IPositionEntity
{
public override List<T> GetList()
{
int positionTypeId = (int)this.PositionType;
using (SqlConnection cn = new SqlConnection(Globals.Instance.ConnectionString))
{
SqlCommand cmd = new SqlCommand("Get_PositionListByPositionTypeId", cn);
cmd.Parameters.Add("@PositionTypeId", SqlDbType.Int).Value = positionTypeId;
cmd.CommandType = CommandType.StoredProcedure;
cn.Open();
return this.GetCollectionFromReader(this.ExecuteReader(cmd));
}
}
}
然后我为每种类型创建了一个类,如下所示(以 CustomerProvider 为例):
public class CustomerProvider
{
public static PositionProvider<CustomerEntity> Instance
{
get
{
if ((int)PositionProvider<CustomerEntity>.Instance.PositionType == 0)
{
PositionProvider<CustomerEntity>.Instance.SetPositionType(PositionType.Customer);
}
return PositionProvider<CustomerEntity>.Instance;
}
}
}
这一切都非常有效......直到我意识到我有一些特定于某些职位类型的功能。 IE。我需要能够根据用户权限获取所有客户(这是一个 IPositionType)。
所以我需要添加另一个抽象方法:
public abstract List<CustomerEntity> GetCustomersByUserPermission(Guid userId);
现在,显然我不希望在我的 PositionProvider 抽象类中使用此方法,因为这意味着在处理网站/公司提供商时会出现该方法。
我怎样才能添加这个和其他额外的方法,而不必在 SqlPositionProvider 中复制代码?
编辑:
我想到的唯一想法是将 PositionProvider 分离为 CustomerProvider、SiteProvider 等的公共(public)属性:
public abstract class CustomerProvider
{
public CustomerProvider()
{
this.Common.SetPositionType(PositionType.Customer);
}
public PositionProvider<CustomerEntity> Common
{
get
{
if (_common == null)
{
DalHelper.CreateInstance<PositionProvider<CustomerEntity>>(out _common);
}
return _common;
}
}
private PositionProvider<CustomerEntity> _common;
public static CustomerProvider Instance
{
get
{
if (_instance == null)
{
DalHelper.CreateInstance<CustomerProvider>(out _instance);
}
return _instance;
}
}
private static CustomerProvider _instance;
public abstract List<CustomerEntity> GetCustomersByUserPermission(Guid userId);
}
这将允许我将特定代码放在 CustomerProvider.Instance.MyNonGenericMethod()
中,然后访问 PositionProvider
我可以做 CustomerProvider.Instance .Common.GetList()
... 不过这看起来确实有点像 hack。
最佳答案
如果我理解正确,你需要一种方法来在子类中包含一些方法,但不是在所有子类中。
如果您可以对所需的额外方法进行分组,则可以使用一个接口(interface),实现它,并在您的子级(组合)中使用这个新类的实例。
对此的简化是所有子类的存储库模式(此示例不使用接口(interface))。
[注意:代码无法编译,仅供演示使用]
public class PositionProviderRepository
{
public List<T> GetList()
{
int positionTypeId = (int)this.PositionType;
using (SqlConnection cn = new SqlConnection(Globals.Instance.ConnectionString))
{
SqlCommand cmd = new SqlCommand("Get_PositionListByPositionTypeId", cn);
cmd.Parameters.Add("@PositionTypeId", SqlDbType.Int).Value = positionTypeId;
cmd.CommandType = CommandType.StoredProcedure;
cn.Open();
return this.GetCollectionFromReader(this.ExecuteReader(cmd));
}
}
public List<CustomerEntity> GetCustomersByUserPermission(Guid userId) {
//TODO: implementation
}
}
然后在所有实体(如 CustomerEntity)中使用此类。
这可以有效地替代您的类 SqlPositionProvider<T>
但我不确定我是否正确理解了您的架构,您的层次结构非常复杂。
关于c# - 需要一些帮助来解决我的 DAL 中的主要抽象模式问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1661549/