我编写了一个通用数据库类,可以调用它来执行通用数据库(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
}
我编写了一个写入数据库的控制台应用程序。执行应用程序时,用户会提供一些命令行开关。
有些开关如下(还有其他与程序操作相关的内容,我没有在这里包含):
/ 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语句来选择构造函数,该方法在上面的逻辑中执行测试,但我只是想知道是否有可能的更优雅的方式来做到这一点?
答案 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