2017-04-20 7 views
1

私は、共通データベース(CRUD)操作を実行して複数のソリューションにADO.NETコードを書き換えないように呼び出すことができる汎用データベースクラスを作成しました。これは柔軟にするために、次のようにクラスがある異なるデータベースの認証タイプとインスタンスタイプなどに基づいて、コンストラクタのオーバーロードがいくつかあります:C#reflection - 利用可能なパラメータに基づいてコンストラクタのオーバーロードを選択する

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 
} 

は、私は、データベースへの書き込みをされたコンソールアプリケーションを書かれています。アプリケーションが実行されると、ユーザーはいくつかのコマンドラインスイッチを提供します。

(私はここに含まれていないプログラムの動作に関連する他の人があります)、次のようにスイッチのいくつかは、次のとおりです。

  • /秒:データベースサーバー名
  • /I:データベースインスタンス名
  • /D:データベース名
  • /N:統合セキュリティ(TrueまたはFalse)
  • /U:DBパスワード:ユーザー名
  • /Pデシベル

/I、/ uと/ pはオプションです(インスタンス名が供給されていない場合はEG、プログラムは/ sの既定のインスタンスに接続することであると仮定し)

したがって、私は必要プログラムは実行時に、どの引数が提供されたかに基づいてどのコンストラクタを呼び出すかを決定します。

ここ

擬似例

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 
     } 
    } 
} 

私は、関連するコンストラクタを実行するためにリフレクションを使用して、私はロジックでテストを行い、Mainメソッドにswitch文を使用して、コンストラクタの選択を実現することができることをすることができます知っていますこれを行うもっとエレガントな方法があるのだろうかと疑問に思っていますか?

+2

デフォルトのconstrutorを使用し、クラスプロパティを使用して入力値をスローするのは簡単です。 – Felype

答えて

1

:単純にこれを使用するこのコンストラクタを呼び出すように

。配列と項目型の項目数に基づいて必要なコンストラクタを自動的に呼び出します。

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 =(データベース)アクティベーター。CreateInstance(typeof(データベース)、引数); それ以外は、うまく動作します - ありがとうございました! – SEarle1986

1

私は非常に簡単なアプローチを提案します。あなたはまた、スイッチtrueあるすべてのオプションを持つ単純なリストを作成することができます

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

:appriatelyあなたのメンバーを設定し、1つのコンストラクタを使用してください。あなたはその後、リフレクションを使用したい場合は、パラメータとして入力し、オブジェクトの配列を受け入れるActivator.CreateInstanceメソッドを使用し、

var instance = Activator.CreateInstance(myType, suppliedParameters); 
関連する問題