我们正在构建一个我们希望最终实现“隐藏”数据访问层的系统(以便我们将来可以更改它)。
因此,我们的想法是应用程序代码将调用将由数据库访问对象实现的接口。所以我们有接口类:
public interface DatabaseInterface
{
void Create(DataObject obj);
}
然后我们有实现接口的类:
public class DatabaseAccess : DatabaseInterface
{
void Create(DataObject obj)
{
Entity dbContext = new Entity();
dbContext.Data.Add (obj);
dbContext.SaveChanged();
}
}
所有这一切,我们有DataObject类:
public class DataObject
{
integer Data1;
string Data2;
}
OUr问题存在于主应用程序中,因为我不知道DatabaseInterface的实现是什么:
public class CreateElementOnDatabase
{
DataObject myObj = new DataObject();
myObj.Data1 = 10;
myObj.Data2 = "Test String";
var dbAccess = new DatabaseInterface() <=== I know this is not possible, but don´t know what to do!!!!
dbAccess.Create (myObj);
}
如何在不知道哪个类的情况下调用已实现的方法?当然我在设计上遗漏了一些东西。
我们真的想让应用程序完全独立于下面的代码。
[编辑1]
这些实现驻留在不同的类库中。所以我有以下内容: 应用项目 DatabaseInterface项目 DatabaseAccess项目 DataObject项目
答案 0 :(得分:3)
你所缺少的是一个&#34;工厂&#34;基于它接收的参数或配置设置为外部世界构建实例的类(如果他们希望外部世界影响其行为)或做出自己的决定,即他们将根据其内部创建A或B类型的实例无法从外部改变的逻辑。 在下面的代码中,您将看到DatabaseFactory,这是您缺少的。另外,请注意私有/公共/内部修饰符,这些修饰符对于确保您公开所需内容并且不超出您的需要(使所有类公开会给想要使用您的库的人造成混淆)非常重要。
这是代码
// interfaces must be public - this is the "contract" with the outside world / assemblies
public interface IDatabase
{
void Create(DataObject obj);
}
// classes that implement interfaces should be internal - outside world don't know about them
internal class SQLDatabase : IDatabase
{
// internal on constructor helps you to make sure you are the only one
// that can create such an instance
internal SQLDatabase()
{
}
void Create(DataObject obj)
{
Entity dbContext = new Entity();
dbContext.Data.Add(obj);
dbContext.SaveChanged();
}
}
internal class OracleDatabase : IDatabase
{
internal OracleDatabase()
{
}
void Create(DataObject obj)
{
//oracle creation method
}
}
public class DataObject
{
int Data1;
string Data2;
}
// this is the factory class that creates the instances for you (ourside world)
public class DatabaseFactory
{
// you can use either params or ideally app.config keys
public IDatabase CreateInstace()
{
if (ConfigSetting == "SQL")
{
return new SQLDatabase();
}
else if (ConfigSetting == "Oracle")
{
return new OracleDatabase();
}
else throw new System.Exception ("invalid configuration setting key");
}
}
// this is in external assembly:
public class CreateElementOnDatabase
{
DataObject myObj = new DataObject();
myObj.Data1 = 10;
myObj.Data2 = "Test String";
// you only work with public interfaces
// and the factory creates the instances for you ...
IDatabase db = DatabaseFactory.CreateInstace();
db.Create(myObj);
}
答案 1 :(得分:0)
您可以创建一个可以创建正确DAL对象的类。 像这样:
public class RepositoryFactory {
public static DatabaseInterface MakeDAL() {
return new DatabaseAccess();
}
}
然后,制作一个DAL对象:
var dbAccess = RepositoryFactory.MakeDAL();
根据应用程序与数据库访问之间的分离程度,您可以将接口,接口实现和工厂类放在单独的程序集中,或者将一些程序集放在一个程序集中,将一些程序集放在另一个程序集中。当你说“完全独立于源代码”时,这取决于你的意思。