我有这个问题:
在C#中,我正在创建一个应该连接到各种数据库的程序(SQLite,SQL Server Compact,MS Access等)。我在app.config中设置了一个名为“dbType”的参数(对于SQLlite可以是1,对于SQL Server Compact可以是2,对于MS Access可以是3,等等)。用户应在程序运行时使用下拉菜单或类似的内容更改此参数。
然后程序读取此参数并创建与所选数据库对应的数据库接口(IDatabase)实现的实例。
代码是:
class ObjectDatabaseCreator
{
protected ObjectDatabase objectDb;
protected Object objectDAO;
protected int dbType;
protected String dbName;
public ObjectDatabaseCreator()
{
}
public ObjectDatabaseCreator(String dbName)
{
this.dbType = ObjectConfiguration.getDbType();
this.dbName = dbName;
}
public ObjectDatabase getObjectDatabase()
{
//1 - SQLite; 2-SQLServer Compact; 3-SQLServer Express; 4-MS Access
switch (dbType)
{
case 1:
objectDb = new ObjectDatabase(new Database_Impl_1(dbName));
break;
case 2:
objectDb = new ObjectDatabase(new Database_Impl_2(dbName));
break;
case 3:
objectDb = new ObjectDatabase(new Database_Impl_3(dbName));
break;
case 4:
objectDb = new ObjectDatabase(new Database_Impl_4(dbName));
break;
}
return objectDb;
}
}
好吧,它似乎有效,但我想知道是否有可能更容易添加其他数据库,我的意思是,如果有另一个数据库我应该修改这个类,重新编译等。
我怎样才能实例化BLL类的其他实现,让我们说Person,Customer等?这些也发生了变化,我应该添加更多类。
谢谢, 状育苗盘
答案 0 :(得分:1)
看看MEF ...它可能很有用,因为它增加了目录的概念。 在文件夹中的程序集中定义任意数量的IDataBaseImplemention类,MEF将允许您“导入”所有找到的类。
MEF包含在.Net框架中(来自V4),但还有许多其他框架可以完成这项工作。
答案 1 :(得分:0)
如果业务类根据所使用的数据库引擎而发生变化,我认为您的设计存在问题。所以我建议规范你的业务类。
关于数据库连接,您应该使用System.Data.Common程序集/命名空间中的DbProviderFactories,DbProviderFactory,DbConnection等。 http://msdn.microsoft.com/en-us/library/9tahwysy.aspx
如果要正确执行此操作,请将与配置文件的connectionString部分一起使用。 http://msdn.microsoft.com/en-us/library/ms178411(v=VS.85).aspx
如果您只想改进当前的实施,那么请将Factories用于您的数据库对象以及业务对象。但实际上,随着时间的推移,这将成为一个问题。
答案 2 :(得分:0)
您可以将整数值中的地图添加到类类型中。像这样(未经测试):
// initialization somewhere:
Dictionary<int,Type> databases = new Dictionary<int,Type>();
databases.Add(1, Database_Impl_1);
databases.Add(2, Database_Impl_2);
// ...
// then later, in getObjectDatabase()
objectDb = new ObjectDatabase(databases[settingValue]);
谷歌控制权的反转 - 有这方面的框架。
答案 3 :(得分:0)
最常用的方法是让用户指定应加载的类型的assembly qualified name。您可以使用以下内容创建对象的类型名称实例:
IDatabase GetDatabase(string typeName)
{
var databaseType = Type.GetType(typeName);
if (databaseType == null)
{
return null;
}
return (IDatabase)Activator.CreateInstance(databaseType);
}
然后,您的用户可以指定IDatabase
的几乎所有实现 - 包括用户提供的程序集中包含的实现:
IDatabase db = GetDatabase("EnterpriseLib.XmlDatabase, EnterpriseLib.XmlDatabase, Version=1.42.0.0, Culture=neutral, PublicKeyToken=AAAAAAAAAAAAAAAA"");
只要程序集包含在程序集搜索路径的其中一个文件夹中,这就可以正常工作。