トップ回答者
WCFサービスの実装クラスが複数ある場合の記述について

質問
-
西脇です。
みなさんのお知恵を拝借させてください。
.NET Remotingでホストしていたサービスを、WCF に移行しようとしています。
.NET Remoting の RemotingConfiguration.Configure メソッドのようなこと(以下サンプル)は、WCFでもできますでしょうか?
using System;
using System.Runtime.Remoting;namespace dotNetRemotingServer
{
class Program
{
static void Main(string[] args)
{
RemotingConfiguration.Configure(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, false);Console.WriteLine(AppDomain.CurrentDomain.SetupInformation.ApplicationName);
Console.WriteLine("<Enter>で終了します。");
Console.ReadLine();
}
}
}
条件
・構成ファイル(app.config)にWCF エンドポイントに関する構成設定を書きたい
・サービスの実装クラスが複数ある
・サービスの実装クラスが増えても WCFホストプロセスのコーディングを変えずに、構成ファイル(app.config)を書きかえるだけですませたい
以上、よろしくお願い致します。
回答
-
素直に考えると、構成ファイルに記述してあるservice要素を参照してループすると思いますが。どうでしょう。
ServiceModelSectionGroup serviceModelSectionGroup = ServiceModelSectionGroup.GetSectionGroup( ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)); foreach (ServiceElement serviceElement in serviceModelSectionGroup.Services.Services) { ServiceHost host = new ServiceHost(System.Type.GetType(serviceElement.Name)); host.Open(); }
私もサービス実装が複数ある理由には興味があるところですが
既存の設計方式に大幅な修正が発生しないですむ。とかが理由なのかしらと想像。
すべての返信
-
そうなんです。
サービスの実装クラスが複数あって、それぞれに対してServiceHostインスタンスを作成するのならできるのですが、RemotingConfiguration.Configure みたく1行で書けないかなぁ・・・。
そして、サービスの実装クラスが増えてもコーディングを変えずに、構成ファイル(app.config)を書きかえるだけですませたいなぁ・・・。
という質問です。
やっぱり、こう書くしかないですか。
using System;
using System.ServiceModel;namespace WcfServer
{
class Program
{
static void Main(string[] args)
{
ServiceHost host1 = new ServiceHost(typeof(WcfService1));
ServiceHost host2 = new ServiceHost(typeof(WcfService2));
ServiceHost host3 = new ServiceHost(typeof(WcfService3));
host1.Open();
host2.Open();
host3.Open();Console.WriteLine(AppDomain.CurrentDomain.SetupInformation.ApplicationName);
Console.WriteLine("<Enter>で終了します。");
Console.ReadLine();
}
}
} -
そうなんです。
サービスの実装クラスが複数ある場合、なのです。
わかりにくくてすみません。
以下のような構成ファイルのパターンです。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="NewBehavior1">
<serviceDebug httpHelpPageUrl="http://localhost:8087/WcfSercice1/help"
httpsHelpPageEnabled="false" />
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8087/WcfSercice1/mex" />
</behavior>
<behavior name="NewBehavior2">
<serviceDebug httpHelpPageUrl="http://localhost:8087/WcfSercice2/help"
httpsHelpPageEnabled="false" />
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8087/WcfSercice2/mex" />
</behavior>
<behavior name="NewBehavior3">
<serviceDebug httpHelpPageUrl="http://localhost:8087/WcfSercice3/help"
httpsHelpPageEnabled="false" />
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8087/WcfSercice3/mex" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="NewBehavior1" name="WcfServer.WcfSercice1">
<endpoint address="http://localhost:8087/WcfSercice1.svc" binding="basicHttpBinding"
bindingConfiguration="" contract="WcfServer.WcfSercice1" />
</service>
<service behaviorConfiguration="NewBehavior2" name="WcfServer.WcfSercice2">
<endpoint address="http://localhost:8087/WcfSercice2.svc" binding="basicHttpBinding"
bindingConfiguration="" contract="WcfServer.WcfSercice2" />
</service>
<service behaviorConfiguration="NewBehavior3" name="WcfServer.WcfSercice3">
<endpoint address="http://localhost:8087/WcfSercice3.svc" binding="basicHttpBinding"
bindingConfiguration="" contract="WcfServer.WcfSercice3" />
</service>
</services>
</system.serviceModel>
</configuration> -
なぜサービスを分けるのか、その辺りはちょっとわかりませんでした。
質問の条件を満たしてはいないかもしれませんが、ヒントということで
Windows プロセス アクティブ化サービスでのホスティング という方法があります。
IISでのホストをもう少し一般化したものです。これを使うとアドレスを登録しておくとあとは自動的に起動されます。
ただし、w3wp.exeというワーカープロセス内で動作します。逆に言うと、WCFをホストするためのWindows Serviceは不要です。(WCF以外の処理ができなくなるとも言います。) -
素直に考えると、構成ファイルに記述してあるservice要素を参照してループすると思いますが。どうでしょう。
ServiceModelSectionGroup serviceModelSectionGroup = ServiceModelSectionGroup.GetSectionGroup( ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)); foreach (ServiceElement serviceElement in serviceModelSectionGroup.Services.Services) { ServiceHost host = new ServiceHost(System.Type.GetType(serviceElement.Name)); host.Open(); }
私もサービス実装が複数ある理由には興味があるところですが
既存の設計方式に大幅な修正が発生しないですむ。とかが理由なのかしらと想像。