簡體   English   中英

如何一次初始化基類屬性,而不是從所有派生類傳遞基類屬性?

[英]How to initialize base class property once instead of passing it from all derived classes?

我有一個小型庫,正在執行1個長時間運行的操作,並基於該操作在數據庫表中保存一些數據。現在這是一個小型庫,其中不包含很多數據庫表操作,因此我使用Ado.net來管理數據訪問層。

我創建了基類,在其中放置了連接字符串和Ado.net命令執行。

我有3-4個類,其中某些方法執行insert,update和delete,但是問題是,每當我創建此類的對象時,我都必須將連接字符串傳遞給這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));

我以為將基類作為具體類,但是比將基類作為抽象類更有意義,我猜這就是為什么我將基類標記為抽象。

有人可以幫我更好地設計嗎?

它可能不是您要查找的答案,但是我將使用配置文件,將其存儲在connstring中,然后在基類中將其設置為靜態變量。

您明確要求的是不可能的。 每個派生類都必須使用其ctor進行初始化,因此每個ctor必須以一種或另一種方式引入連接字符串。 你可以:

  • 使用一個工廠類,該工廠類在其ctor中獲取一次連接字符串,然后返回使用該連接字符串初始化的repo對象,如下所示:
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 (可能從配置文件讀取該值),然后將其注入到您的各種存儲庫中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM