2016-07-27 7 views
-2

サードパーティの.NET APIからオブジェクトを処理するアプリケーションを開発しています。プロセッサは、次のIProcessorインターフェイスを実装することによって作成されます。サードパーティのAPIに依存するクラスの部分を別のアセンブリに分割する

public interface IProcessor 
{ 
    Process(ApiClass input); 
} 

このインターフェイスの具体的な実装では、特定のプロセッサの動作を制御するための他のプロパティも追加できます。たとえば...

public class ProcessorA : IProcessor 
{ 
    public double X; 
    public double Y; 

    public Process(ApiClass input) 
    { 
     //Code here... 
    } 
} 

public class ProcessorB : IProcessor 
{ 
    public string MyParameter; 
    public string MyOtherParameter; 

    public Process(ApiClass input) 
    { 
     //Code here... 
    } 
} 

サードパーティのAPIとネイティブアプリケーション内からApiClassのみ機能します。しかし、私は、他の.NETアセンブリを作成して、プロセッサを読み書きすることはできますが、サードパーティのAPIを参照する必要はありません。具体的には、JSONとの間でプロセッサをシリアル化/逆シリアル化できるようにしたいと考えています。

したがって、プロセッサのパラメータとその実装をIProcessor.Process()の2つの別々のアセンブリに分割する最適な方法を決定しようとしています。第三者APIを参照するものとそうでないもの。

1つのオプションは、オブジェクトの複製プロキシバージョンを作成することです。

ただし、これらのクラス間でプロパティを同期させておく必要があります。私はそれらの間で翻訳するためのマッピングコードを書く必要があります。

また、パラメータをプロキシクラスに格納し、Process()メソッドを追加するこのクラスを継承するクラスを作成することもできます。

//In assembly that does NOT reference 3rd party API 
public class ProcessorA 
{ 
    public double X; 
    public double Y; 
} 

//In assembly that references 3rd party API 
public class ProcessorA : ProcessorAProxy 
{ 
    public Process(ApiClass input) 
    { 
     //Code here... 
    } 
} 

このオプションには、同期をとる必要がある重複するプロパティがなくなりました。しかし、私がProcessorAProxyを非直列化すると、マッピング値をもう一度扱わなくても、それを実際のProcessorAにどのように変換できるかわかりません。

継承するクラスの代わりに、そのコンストラクタを使って実際に処理を行うクラスにオプションを注入することもできます。

//In assembly that does NOT reference 3rd party API 
public class ProcessorAOptions: IOptions 
{ 
    public double X; 
    public double Y; 
} 

//In assembly that references 3rd party API 
public class ProcessorA : IProcessor 
{ 
    public ProcessorAOptions Options; 

    public ProcessorA(ProcessorAOptions opt) 
    { 
     Options = opt; 
    } 

    public Process(ApiClass input) 
    { 
     //Code here... 
    } 
} 

私はその後、その後、IProcessorの正しい具体的なタイプのコンストラクタに渡される必要があるだろうIOptionsの特定のタイプを、デシリアライズでしょう。これはProcessorFactoryで処理できます。

IOptions options = serializer.Read(); //Read the some options 
ProcessorFactory fact = new ProcessorFactory(); //Create a factory 
IProcessor proc = fact.GetProcessor(options); //Get the processor for options from the factory 

これまでのところ私は、このオプションが一番好き、私はProcessorFactoryが正しいIProcessor型にIOptionsの特定の種類の中からマップするための最良の方法はよく分かりません。

1つのオプションは、各オプションをチェックする巨大なif文を作成することです。

これは機能しますが、特にプロセッサの種類が多い場合は、やや効率が悪いようです。

もう1つの選択肢は、慣習とリフレクションを使用することです。たとえば、IProcessorを実装するクラスを見つけ、特定のIOptionsタイプをパラメータとして持つコンストラクタを持っています。または、オプションの接尾辞を削除したオプションクラスの名前と同じ名前のクラスを見つけることができます(ProcessorBOptions - > ProcessorB)。

リフレクションを使用すると良い選択肢がありますか?全体的に、第三者APIを参照するコードと、別のアセンブリのクラスにないコードを分割して、互いにどのようにマッピングするのが良いでしょうか?

答えて

0

最後の方法は、WebRequestがCLRでどのように機能するかと似ています。 UriをCreateに渡し、正しいサブクラスを返します。

https://msdn.microsoft.com/en-us/library/system.net.webrequest(v=vs.110).aspx

あなたはWebRequest.Createのリファレンス・ソースを見れば、あなたは、Microsoftが使用するパターンのいくつかを実行することができます。一般的に

http://referencesource.microsoft.com/#System/net/System/Net/WebRequest.cs,117

http://referencesource.microsoft.com/#System/net/System/Net/Internal.cs,1608

、それはつまるところ内部ルックアップから型の名前を取り出し、適切な派生型を返すためにActivator.CreateInstanceを使用します。

https://msdn.microsoft.com/en-us/library/system.activator.createinstance(v=vs.110).aspx

関連する問題