0

最終的な実装でデータ アクセス レイヤーを「非表示」にするシステムを構築しています (将来変更できるようにするため)。

つまり、アプリケーション コードは、データベース アクセス オブジェクトによって実装されるインターフェイスを呼び出すということです。したがって、インターフェースクラスがあります:

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

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 プロジェクト

4

2 に答える 2

3

あなたが見逃しているのは、受け取ったパラメーターまたは構成設定に基づいて外界のインスタンスを構築する「ファクトリー」クラスです(外界がその動作に影響を与えたい場合)、または独自の決定を下します。つまり、インスタンスを作成します外部から変更できない内部ロジックに基づいて、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);
}
于 2013-08-26T21:01:31.877 に答える
0

正しい DAL オブジェクトを作成するクラスを作成できます。このようなもの:

public class RepositoryFactory {
    public static DatabaseInterface MakeDAL() {
        return new DatabaseAccess();
    }
}

次に、DAL オブジェクトを作成します。

var dbAccess = RepositoryFactory.MakeDAL();

アプリとデータベース アクセスをどの程度分離するかによって、インターフェイス、インターフェイスの実装、およびファクトリ クラスを個別のアセンブリに配置するか、一部を 1 つのアセンブリに配置し、一部を別のアセンブリに配置します。「ソースコードから完全に独立している」と言うとき、それはあなたが何を意味するかによって異なります。

于 2013-08-26T20:47:16.953 に答える