2017-04-20 55 views
1

我寫了一個通用數據庫類,可以調用它來執行通用數據庫(CRUD)操作,以節省在多個解決方案中重寫ADO.NET代碼。爲了使這種靈活的,有基於不同數據庫的認證方式和實例類型等類如下一些構造函數重載的:C#反射 - 根據可用參數選擇構造函數過載

class Database 
{ 
    // default instance with Windows authentication 
    // constructor 1 
    public Database(string server, string database, bool persistSecurityInfo) 
    { 
     _server = server; 
     _database = database; 
     _persistSecurityInfo = persistSecurityInfo; 
     _integratedSecurity = "True"; 
     _connectionString = "Data Source=" + server + ";Initial Catalog=" + database + ";Persist Security Info=" + persistSecurityInfo.ToString() + ";Integrated Security=True"; 
    } 

    // named instance using Windows authentication 
    // constructor 2 
    public Database(string server, string instance, string database, bool persistSecurityInfo) : this(server, database, persistSecurityInfo) 
    { 
     _instance = instance; 
     _integratedSecurity = "True"; 
     _connectionString = "Data Source=" + server + "\\" + instance + ";Initial Catalog=" + database + ";Persist Security Info=" + persistSecurityInfo.ToString() + ";Integrated Security=True"; 
    } 

    // default instance with SQL authentication 
    // constructor 3 
    public Database(string server, string database, bool persistSecurityInfo, string userName, string password) : this(server, database, persistSecurityInfo) 
    { 
     _userName = userName; 
     _password = password; 
     _integratedSecurity = "False"; 
     _connectionString = "Data Source=" + server + ";Initial Catalog=" + database + ";Persist Security Info=" + persistSecurityInfo.ToString() + ";User ID=" + userName + ";Password=" + password; 
    } 

    // named instance with SQL authentication 
    // constructor 4 
    public Database(string server, string instance, string database, bool persistSecurityInfo, string userName, string password) : this(server, database, persistSecurityInfo, userName, password) 
    { 
     _instance = instance; 
     _integratedSecurity = "False"; 
     _connectionString = "Data Source=" + server + "\\" + instance + ";Initial Catalog=" + database + ";Persist Security Info=" + persistSecurityInfo.ToString() + ";User ID=" + userName + ";Password=" + password; 
    } 

    private string _server; 
    private string _instance; 
    private string _database; 
    private bool _persistSecurityInfo; 
    private string _userName; 
    private string _password; 
    private string _integratedSecurity; 

    private string _connectionString; 
    private string _query; 

    //CRUD Methods here 
} 

我寫這寫數據庫的控制檯應用程序。當應用程序執行時,用戶提供一些命令行開關。

是一些開關如下(有涉及到我這裏沒有包括程序的操作等):

  • /S:數據庫服務器名稱
  • /我:數據庫實例名
  • /d:數據庫名
  • /N:集成安全(TRUE或FALSE)
  • /U:DB名
  • /p:DB密碼

/I,/ u和/ p是可選的(例如,如果沒有被提供一個實例名,該程序假設它是連接到默認實例上/秒)

因此,我需要程序在運行時根據提供的參數決定調用哪個構造函數。

這裏

僞例如

Class Program 
{ 
    static void Main(string[] args) 
    { 
     foreach (string arg in args[]) 
     { 
      //code to work out which parameters have been provided here and adds them to array. Also other code which checks integrity such as ensuring there is no username without a password and vice versa etc. 
      string[] suppliedParameters; 

      //if there is a /i , /u , /p parameters, use constructor 4 
      //if there is a /u and /p but no /i, use constructor 3 
      //if there is an /i but no /u or /n use constructor 2 
      //if there is no /i, /u or /n, use constructor 1 
     } 
    } 
} 

我知道我可以使用反射來執行相關的構造,並且我可以在其中執行的邏輯測試的主要方法使用switch語句實現的構造函數的選擇以上,但我只是想知道是否有一個更優雅的方式來做到這一點?

+2

它對你來說只是使用一個默認的構造函數,然後使用類屬性來引入輸入值。 – Felype

回答

1

如果你想使用反射,然後,用Activator.CreateInstance方法,它接受一個類型和對象作爲參數數組。它將根據數組和項目類型中的項目數量自動調用所需的構造函數。

object[] arguments = //Create array based on input 
DataBase db=(DataBase)Activator.CreateInstance(typeof(Database), arguments); // This will call matching constructor based on array passed 
+0

看起來正是我想要的,我會給它一個 – SEarle1986

+0

標記爲答案,如果找到你的答案 – CreativeManix

+0

我不得不投入如下類型數據庫 DataBase db =(Database)Activator。CreateInstance(typeof(Database),arguments); 但除此之外,它是行之有效 - 謝謝! – SEarle1986

1

我建議一個比較簡單的方法。使用appriately設置你的成員一個一個構造函數:

public MyClass(params string[] switches) 
{ 
    if(switches.Contains("/i") this.i = ... 
    ... 
} 

你也可以創建一個簡單的清單,其開關true所有選項。

調用此構造函數簡單地使用這樣的:

var instance = Activator.CreateInstance(myType, suppliedParameters);