2017-11-16 1 views
1

は、私は、外部DLLへの参照を持っているプログラムを持って、同じ機能を持つ別のライブラリをロードを動的に

magic.externalFunctions.nosql.dll 

これらのDLLは、同じ機能を提供する外部ライブラリです。パブリックメソッドとプロパティさえ同じです。しかし、には、InterfaceクラスまたはBaseクラスがありません。

ここでは、ターゲットシステムに応じて、これらの2つのライブラリを選択する必要があります。彼らはが共通でインタフェースを持っているならば、私のようなものだろう:

public class DoDatabaseStuff() { 
    private IMagic _magic 
    public DoDatabaseStuff(bool useNoSql) { 
     if (useNoSql) { 
     _magic=new SqlMagic(); 
     } else { 
     _magic=new NoSqlMagic(); 
     } 
     myTable=_magic.Table.Create("CustomerTable"); 
     myTable.Columns.Add(typeof(int),"ID"); 
     myTable.Columns.Add(typeof(string),"Name"); 
    } 
} 

を反射過剰な量を使用せずにこの問題を解決する方法はありますか?私はまだmyTable.Columns.Add()の代わりにtableType.GetMethod("Add").Invoke()...の代わりに

のようなものを使用したいと思います。異なるビルド構成を使用しているcsprojの条件も使いたくないです。これは理論上は機能しますが、csprojが自動的に変更されるたびに乱れます(例:ナゲットパッケージのアップデート)

+0

同じことをする複数のライブラリを切り替える必要がある理由は何ですか?確かに非効率的な方法であり、依存関係の数が増える – jasttim

+0

しかし、これを行う必要があれば、ヘルパー・メソッドを作成してSQLライブラリを呼び出し、NON SQLライブラリを呼び出すことができます – jasttim

+0

プログラムを2つの異なるプラットフォームにインストールします。現時点では、同じソースファイルを含んでいるが参照が異なる2つのプロジェクトがありますが、構造が変更された場合はエラーの大きな原因になります。同様の問題を回避するために、2つの異なるgitブランチを作成しようとしました。ここでの主な問題は、EXTERNALライブラリです。これが私たち自身のコードであれば、これを別の方法でやったでしょう。 –

答えて

5

あなたが変更できない悪い設計に直面したときには、あなたのコードからの設計。この場合、外部アセンブリが不足している共通インタフェースを作成する必要があります。

アダプターを使用して、コードのコアから初期の設計上の欠陥を保護する統一されたインターフェイスを提供できます。

あなたがアクセスをしたい元のクラスの抽象化を作成して起動します。

public interface IMagic { 
    ITable CreateTable(string name); 
} 

public interface ITable { 
    void AddColumn(Type type, string name); 
} 

その後、あなたはアダプタを提供します。

class SqlMagicAdapter : IMagic { 
    SqlMagic m_innerMagic = new SqlMagic(); 

    ITable CreateTable(string name) { 
     return new SqlTableAdapter(m_innerMagic.Table.Create(name)); 
    } 
} 

class SqlTableAdapter : ITable { 
    SqlTable m_innerTable; 
    public SqlTableAdapter(SqlTable innerTable) { 
     m_innerTable = innerTable; 
    } 
    void AddColumn(Type type, string name) { 
     m_innerTable.Columns.Add(type, name); 
    } 
} 

class NoSqlMagicAdapter : IMagic { 
    NoSqlMagic m_innerMagic = new NoSqlMagic(); 

    ITable CreateTable(string name) { 
     return new NoSqlTableAdapter(m_innerMagic.Table.Create(name)); 
    } 
} 

class NoSqlTableAdapter : ITable { 
    NoSqlTable m_innerTable; 
    public NoSqlTableAdapter(NoSqlTable innerTable) { 
     m_innerTable = innerTable; 
    } 
    void AddColumn(Type type, string name) { 
     m_innerTable.Columns.Add(type, name); 
    } 

ファクトリメソッドを使用すると、それぞれのアダプターを返すことができます。

public static class MagicFactory { 
    public static IMagic GetMagic(bool useNoSql) { 
     if (useNoSql) { 
      return new NoSqlMagic(); 
     } 
     else { 
      return new SqlMagic(); 
     } 
    } 
} 

あなたのコアコードは、t彼は工場で返される抽象化:

public class DoDatabaseStuff() { 
    private IMagic _magic 
    public DoDatabaseStuff(bool useNoSql) { 
     _magic = MagicFactory.GetMagic(useNoSql); 
     ITable myTable = _magic.CreateTable("CustomerTable"); 
     myTable.AddColumn(typeof(int), "ID"); 
     myTable.AddColumn(typeof(string), "Name"); 
    } 
} 

は、Anが、たとえば、利点は、あなたも任意の将来の変更のための準備ができているということである以前のものと互換性がありませんまだ別の更新外部ライブラリを追加しました。コアコードを変更することなく、これらの新しい機能を簡単にサポートすることができます。