如何初始化一次基类属性,而不是从所有派生类传递它?



>我有一个小库,我在其中执行 1 个长时间运行的操作,并基于该操作,我将一些数据保存在数据库表中。现在这是一个小库,不包括很多数据库表操作,因此我使用 Ado.net 来管理数据访问层。

我创建了基类,在其中放置了连接字符串和 Ado.net 命令执行。

我有 3-4 个类,其中一些方法执行插入、更新和删除,但问题是每当我创建此类的对象时,我都必须将连接字符串传递给这 4 个类中的每一个。

法典:

internal abstract class BaseRepo
{
private readonly string connectionString;
protected int TestId;
protected int VariantId;

public BaseRepo() { }
protected BaseRepo(string connection)
{
this.connectionString = connection;
}
internal virtual void ExecuteQuery(string query,
IList<SqlParameter> parameters)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(query, conn))
{
conn.Open();
foreach (SqlParameter parameter in parameters)
{
command.Parameters.Add(parameter);
}
command.ExecuteNonQuery();
}
}
}
internal virtual void ExecuteQueryWithTransaction(SqlConnection connection,SqlTransaction transaction, string query,
IList<SqlParameter> parameters)
{
using (SqlCommand command = new SqlCommand(query, connection, transaction))
{
foreach (SqlParameter parameter in parameters)
{
command.Parameters.Add(parameter);
}
command.ExecuteNonQuery();
}
}
internal virtual int ExecuteScalar(string query,
IList<SqlParameter> parameters)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(query, conn))
{
conn.Open();
foreach (SqlParameter parameter in parameters)
{
command.Parameters.Add(parameter);
}
var data = command.ExecuteScalar();
if (data == null)
return 0;
return (int)data;
}
}
}
}

internal class VariantRepo : BaseRepo
{
public VariantRepo(string connectionString,int testId,int variantId) : base(connectionString)
{
TestId = testId;
VariantId = variantId;
}
public VariantRepo(testId) : base(connectionString)
{
TestId = testId;
}
public void DeleteVariantData()
{
string query = "";
List<SqlParameter> parameters = new List<SqlParameter>();
parameters.Add(new SqlParameter("@TestId", TestId));
parameters.Add(new SqlParameter("@VariantId", VariantId));
ExecuteQuery(query, parameters);
}
}
internal class RegionRepo : BaseRepo
{
public RegionRepo(string connectionString, int variantId) : base(connectionString)
{
VariantId = variantId;
}
public int GetRegionIdByVariantId()
{
string query = "";
List<SqlParameter> parameters = new List<SqlParameter>();
parameters.Add(new SqlParameter("@id", VariantId));
return ExecuteScalar(query, parameters);
}
}

如您所见,我这里有 4 个类,从每个类中,我都必须将连接字符串传递给基类:

1)VariantRepo

2)RegionRepo

3)CategoryRepo(未显示,但与上述2相同)

4)TestRepo(未显示,但与上述2相同)。

因此,我想在这里解决两件事:

1)是否可以设计基类,我只需要传递一次连接字符串,而不是为4个具体类中的每一个传递一次?

2)我想将其隐藏在某个类后面的脏逻辑(Sql parameter creation code)下面以获得更好的可读性,因为我必须在很多地方执行此操作:

List<SqlParameter> parameters = new List<SqlParameter>();
parameters.Add(new SqlParameter("@TestId", TestId));
parameters.Add(new SqlParameter("@VariantId", VariantId));

我认为将基类作为具体类,但比将基类作为抽象类更有意义,我想这就是为什么我将基类标记为抽象的原因。

有人可以帮我以更好的方式设计吗?

这可能不是您要查找的答案,但是我会使用一个配置文件,我将连接字符串存储在其中,然后将其设置为基类中的静态变量。

你明确要求的东西是不可能的。每个派生类都必须可以使用其 ctor 进行初始化,因此每个 ctor 都必须以某种方式接收连接字符串。 您可以:

  • 使用工厂类,该类在其 ctor 中获取一次连接字符串,然后返回使用该连接字符串初始化的存储库对象,如
class RepoFactory
{
private readonly string _connectionString;
public RepoFactory(string connectionString)
{
_connectionString = connectionString;
}
public VariantRepo GetVariantRepo(int testId, int variantId) => 
new VariantRepo(_connectionString, testId, variantId);
...
}
  • 在整个代码中使用依赖关系注入,创建一个ConnectionStringProvider类或类似类,该类将具有仅获取属性ConnectionString(可能从配置文件中读取该值),然后将其注入到各种存储库中。

最新更新