C#reflection - 根据可用参数选择构造函数重载

时间:2017-04-20 11:19:05

标签: c# sql database reflection

我编写了一个通用数据库类,可以调用它来执行通用数据库(CRUD)操作,以保存在多个解决方案中重写ADO.NET代码。为了使其灵活,基于不同的数据库身份验证类型和实例类型等,有许多构造函数重载。类如下:

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:数据库服务器名称
  • / i:数据库实例名称
  • / d:数据库名称
  • / n:综合安全(真或假)
  • / u:db用户名
  • / p:db Password

/ 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 个答案:

答案 0 :(得分:1)

我建议采用一种非常简单的方法。使用一个可以适当设置成员的构造函数:

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

您还可以创建一个简单列表,其中包含切换为true的所有选项。

要调用此构造函数,只需使用:

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

答案 1 :(得分:1)

如果要使用Reflection,请使用 Activator.CreateInstance 方法,该方法接受对象的Type和Array作为参数。它将根据数组和项类型中的项数自动调用所需的构造函数。

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