複数の WCF サービスをホストする必要があるアプリケーションを作成しています。WCF の強みの 1 つは、app.config ファイルで設定を指定することにより、再コンパイルせずにサービスを構成できることです。
セルフホスティングの場合、app.config ファイルにあるサービスを自動的にホストするすぐに使える方法はないようです。実行時に app.config にリストされているサービスを動的に列挙し、それぞれに対して ServiceHost を作成するという可能な解決策について言及しているこの質問を見つけました。
ただし、私のサービス、コントラクト、およびホスティング アプリケーションはすべて別のアセンブリにあります。これにより、別のアセンブリで定義されているためType.GetType(string name)
、サービス タイプ (戻り値) を見つけることができません。null
app.config ファイルにリストされているすべてのサービスを動的に確実にホストするにはどうすればよいですか (つまり、new ServiceHost(typeof(MyService))
自己ホスティング アプリケーションでハードコーディングする必要はありませんか?
注: 私の app.config は、Visual Studio 2010 の「WCF 構成エディター」を使用して生成されました。
注: 私の主な目標は、これを app.config ファイルによって駆動することであり、これにより単一の構成ポイントが存在します。これを別の場所で構成する必要はありません。
編集: app.config ファイルを読み取ることができます (こちらを参照) が、さまざまなアセンブリの型を解決できる必要があります。
編集: 以下の回答の 1 つにより、基本的な型名だけでなく、app.config で AssemblyQualifiedName を指定するように促されました。これはType.GetType()
問題を回避することができましたが、どのようにタイプを取得したかに関係なく、ServiceHost.Open()
今では失敗します:InvalidOperationException
// Fails
string typeName = typeof(MyService).AssemblyQualifiedName;
Type myType = Type.GetType(typeName);
ServiceHost host = new ServiceHost(myType);
host.Open(); // throws InvalidOperationException
// Also fails
Type myType2 = typeof(MyService);
ServiceHost host2 = new ServiceHost(myType2);
host2.Open(); // throws InvalidOperationException
例外の詳細:
Service 'SO.Example.MyService' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.
app.config ファイルを内部で解析するときに、WCF がサービス名のリテラル文字列を照合しようとしていると思います。
編集/回答:私がやったことは、基本的に以下の回答にあったものでした。使用する代わりにType.GetType()
、すべてのサービスが同じアセンブリにあることがわかっているので、次のように切り替えました。
// Get a reference to the assembly which contain all of the service implementations.
Assembly implementationAssembly = Assembly.GetAssembly(typeof(MyService));
...
// When loading the type for the service, load it from the implementing assembly.
Type implementation = implementationAssembly.GetType(serviceElement.Name);