この問題を解決するために考えられること、または見つけられることをすべて試して、一日中検索して無駄にしました。最初の WCF サービスを構築し、IIS でホストするのはクールだと思いました。長く続くサービスなので仕方ないですね。それ以来、WCF サービスをホストする別のプロジェクトをソリューションに追加し、WCF プロジェクトを参照しましたが、コードからホストしようとして絶え間なく苦労しています。ホストの実装に関するガイダンスについては、主にhttp://msdn.microsoft.com/en-us/library/ms733069.aspxに従いましたが、特定の状況に合わせて微調整しました。
現在の課題は、ホスティング プロジェクトの App.config で定義されているサービス エンドポイントを取得することです。「エンドポイント」の「コントラクト」属性を WCF サービス コントラクトに解決できません。
WCF アセンブリ
namespace WcfFoldingService
{
[ServiceContract(SessionMode=SessionMode.Required, CallbackContract=typeof(IFoldingUpdaterClientContract))]
public interface IFoldingUpdaterServiceBehavior
{
[OperationContract(IsOneWay = false, IsInitiating = true)]
void Subscribe();
[OperationContract(IsOneWay = false, IsTerminating = true)]
void Unsubscribe();
[OperationContract(IsOneWay = true)]
void PublishSomeOperation();
}
public interface IFoldingUpdaterClientContract
{
[OperationContract(IsOneWay = true)]
void SomeOperation();
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession, ConcurrencyMode=ConcurrencyMode.Single)]
public class FoldingUpdaterService : IFoldingUpdaterServiceBehavior
{
// Omitted for brevity, but complete implementation exists.
}
}
/WCF アセンブリ
ホスティング アセンブリ
App.config
<system.serviceModel>
<services>
<service name="WcfFoldingService.FoldingUpdaterService" behaviorConfiguration="httpServiceBehavior">
<endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="ServiceBindingConfiguration" contract="WcfFoldingService.IFoldingUpdaterServiceBehavior"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<protocolMapping>
<add scheme="http" binding="wsDualHttpBinding" bindingConfiguration="ServiceBindingConfiguration"/>
</protocolMapping>
<bindings>
<wsDualHttpBinding>
<binding name="ServiceBindingConfiguration">
<reliableSession ordered="true"/>
<security mode="None"/>
</binding>
</wsDualHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="httpServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="100" maxConcurrentSessions="100"/>
<sendMessageChannelCache allowUnsafeCaching="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
/ホスティング アセンブリ
Message:
The 'contract' attribute is invalid - The value 'WcfFoldingService.IFoldingUpdaterServiceBehavior' is invalid according to its datatype 'serviceContractType' - The Enumeration constraint failed.
私は困惑しています。Google は関連するリンクをほとんど提供しておらず、ほとんどの場合、私が経験していない他の構成の問題に関係しています。WCF アセンブリが参照されています。私は完全修飾名を使用しています。何らかの形で名前空間の競合が発生した場合に備えて、ConfigurationName 属性を使用してみました。私はWCFが初めてなので、これが明らかな問題であることを願っています!
編集: App.config XML ではなく、プログラムによる構成を使用しています。最も重要なステートメントはContractDescription.GetContract(serviceType)
、new ContractDescription("FullNamespace.IContract")
XML 構成とまったく同じように失敗したことです。serviceType の FullName プロパティの Type オブジェクトは、私の「FullNamespace.IContract」とまったく同じです。コード内でアセンブリへのハード参照がないとアセンブリが読み込まれないという問題があると思われますが、現時点では確信が持てません。今のところ、このアプローチは問題なく機能します。
using (var host = new ServiceHost(typeof(FoldingUpdaterService), baseAddress))
{
var serviceType = typeof (IFoldingUpdaterServiceBehavior);
var serviceContract = ContractDescription.GetContract(serviceType);
var foldingEndpoint = new ServiceEndpoint(serviceContract)
{
Binding = new WSDualHttpBinding()
Address = new EndpointAddress(new Properties.Settings().WcfUpdaterServiceAddress)
};
host.Description.Endpoints.Add(foldingEndpoint);
[...]