1

次の 3 つのプロジェクトで構成される新しいソリューションを設計しています。

「サーバー」 - WCF サービス

「クライアント」 - WCF サービスを呼び出す winforms アプリ

"ServiceContract" - いくつかの基本クラスと WCF サービス コントラクト (インターフェイス) を含むクラス ライブラリ。これは明らかにサーバーによって参照され、クライアントによっても参照されます(ChannelFactoryVSにサービス参照を生成させるのではなく、を使用しています)。サービス コントラクトは次のようになります。

[ServiceContract]
[ServiceKnownType("GetCommandTypes", typeof(CommandTypesProvider))]
public interface INuService
{
    [OperationContract]
    bool ExecuteCommand(CommandBase command);
}

これは非常に基本的な操作です。クライアントは「コマンド」オブジェクトを作成し、それをサーバーに送信して実行します。多くの異なるコマンドがあり、すべて継承されますCommandBase(この基本クラスは "ServiceContract" プロジェクトにあります)。WCF 操作シグネチャで基本クラスを使用しているため、ServiceKnownType属性を使用して動的に実行している既知の型を指定する必要があります。CommandTypesProviderこれは、から派生したすべてのタイプを返すヘルパー クラス ( ) を参照しますCommandBase

「ServiceContract」プロジェクトに存在するいくつかの派生コマンド クラスを使用して、簡単な概念実証を作成しました。したがって、ヘルパー クラスは、実行中のアセンブリの型を反映するだけで済みます。これはすべてうまくいきます。

私の「実際の」ソリューションでは、これらのコマンドクラスは異なるプロジェクトになります。これらのプロジェクトは、その逆ではなく ServiceContract プロジェクトを参照するため、ヘルパーが「コマンド」アセンブリを反映することが困難 (または不可能) になります。私の質問は、既知の型をどのように提供できますか?

私が考えたオプション: -

  • 「サーバー」プロジェクトと「クライアント」プロジェクトは、「ServiceContract」プロジェクトさまざまな「コマンド」プロジェクトの両方を参照します。私のヘルパーは をリフレクトできますAppDomain.CurrentDomain.GetAssemblies()が、「コマンド」アセンブリがすべて読み込まれていないため、これは失敗します (それぞれの型を参照することでこれを強制できますが、それは正しくないと感じます - 動的でプラグ可能なアーキテクチャにしたいので、新しいコマンド プロジェクトを追加するたびにコードを変更する必要はありません)。
  • config で既知のタイプを指定します。ここでも、コマンド クラスを追加するたびに構成を更新する必要がなく、アプリが動的であると便利です。
  • クライアントとサーバーの両方で基になる DataContractSerializer にアクセスし、既知の型を渡す方法はありますか? アセンブリが読み込まれていない限り、アセンブリを反映できないという同じ問題がまだあると思います。
  • ServiceContract プロジェクトがさまざまなコマンド プロジェクトを参照できるようにリファクタリングします。次に、「Assembly.GetReferencedAssemblies()」を使用してそれらを反映できます。さまざまなコマンド クラスサービス コントラクトの一部になっているのではないでしょうか。編集:これには、ロードされたアセンブリのみを見つけるという同じ問題があるようです。

どんなアイデアでも大歓迎です!それは達成できるものですか、それともアーキテクチャを再考する必要がありますか?!

前もって感謝します。

4

2 に答える 2

1

考慮すべきことの 1 つは、DataContractResolver の使用です。

いくつかのリソース:

WCF 拡張性 – Carlos によるデータ コントラクト リゾルバー

ケリーによるDataContractResolver を使用した拡張可能な WCF サービス インターフェイスの構築

既知の型を動的に構成する - YoussefによるDataContractResolver の紹介

于 2012-05-16T22:43:53.227 に答える
0

DataContractResolverの担当者に関する返信をありがとうございます。私はおそらく通常このルートをたどっていただろうが、ウィンザーを使用していたので、代わりにこれを使用して解決策を思いつくことができた。

興味のある人のために、IWindsorInstallerWindsorのを使用して実行される各「コマンド」プロジェクトにWindsorインストーラー()を追加しましたcontainer.Install(FromAssembly.InDirectory...。これらのインストールは、そのプロジェクト内で必要な依存関係を登録する役割を果たします。さらに、既知のタイプヘルパーがコンテナーから解決できるすべてのコマンドクラスも登録します。

于 2012-05-17T07:48:20.283 に答える