次の 3 つのプロジェクトで構成される新しいソリューションを設計しています。
「サーバー」 - WCF サービス
「クライアント」 - WCF サービスを呼び出す winforms アプリ
"ServiceContract" - いくつかの基本クラスと WCF サービス コントラクト (インターフェイス) を含むクラス ライブラリ。これは明らかにサーバーによって参照され、クライアントによっても参照されます(ChannelFactory
VSにサービス参照を生成させるのではなく、を使用しています)。サービス コントラクトは次のようになります。
[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()」を使用してそれらを反映できます。さまざまなコマンド クラスがサービス コントラクトの一部になっているのではないでしょうか。編集:これには、ロードされたアセンブリのみを見つけるという同じ問題があるようです。
どんなアイデアでも大歓迎です!それは達成できるものですか、それともアーキテクチャを再考する必要がありますか?!
前もって感謝します。