私の WCF サービスには、受信メッセージを XML スキーマに対して生の XML として検証するためのカスタム メッセージ インスペクターがあります。メッセージ インスペクターには、いくつかの依存関係があります (ロガーや XML スキーマ コレクションなど)。私の質問は、これらのカスタム動作をインスタンス化し、依存関係を自動的に注入するために、依存性注入フレームワーク (私は現在 Ninject を使用しています) を使用できますか?
概念を示す簡単な例を作成しました。
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using Ninject.Extensions.Logging;
public class LogMessageInspector : IDispatchMessageInspector
{
private readonly ILogger log;
public LogMessageInspector(ILogger log)
{
this.log = log;
}
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
LogMessage(ref request);
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
LogMessage(ref reply);
}
private void LogMessage(ref Message message)
{
//... copy the message and log using this.log ...
}
}
public class LogMessageBehavior : IEndpointBehavior
{
private readonly IDispatchMessageInspector inspector;
public LogMessageBehavior(IDispatchMessageInspector inspector)
{
this.inspector = inspector;
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { }
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this.inspector);
}
public void Validate(ServiceEndpoint endpoint) { }
}
anと aを に挿入ILogger
するにはどうすればよいですか?LogMessageInspector
LogMessageInspector
LogMessageBehavior
2番目の質問、これはやり過ぎですか?
編集:Ninjectを使用して動作を作成するため、コードでサービスを構築すると、これを機能させることができます。ただし、構成を介してサービスを構成する場合は、拡張するクラスを追加する必要がありますBehaviorExtensionElement
。このクラスは WCF によって作成され、代わりに Ninject によって作成されるようにする方法が見つからないようです。コードで設定:
static void Main(string[] args)
{
using (IKernel kernel = new StandardKernel())
{
kernel.Bind<IEchoService>().To<EchoService>();
kernel.Bind<LogMessageInspector>().ToSelf();
kernel.Bind<LogMessageBehavior>().ToSelf();
NinjectServiceHost<EchoService> host = kernel.Get<NinjectServiceHost<EchoService>>();
ServiceEndpoint endpoint = host.AddServiceEndpoint(
typeof(IEchoService),
new NetNamedPipeBinding(),
"net.pipe://localhost/EchoService"
);
endpoint.Behaviors.Add(kernel.Get<LogMessageBehavior>());
host.Open();
Console.WriteLine("Server started, press enter to exit");
Console.ReadLine();
}
}
これは正常に動作しますが、 my を介して構成されたときに動作を作成する方法がわかりませんapp.config
:
<system.serviceModel>
<services>
<service name="Service.EchoService">
<endpoint address="net.pipe://localhost/EchoService"
binding="netNamedPipeBinding"
contract="Contracts.IEchoService"
behaviorConfiguration="LogBehaviour"
/>
</service>
</services>
<extensions>
<behaviorExtensions>
<add name="logMessages" type="Service.LogMessagesExtensionElement, Service" />
</behaviorExtensions>
</extensions>
<behaviors>
<endpointBehaviors>
<behavior name="LogBehaviour">
<logMessages />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
public class LogMessagesExtensionElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof(LogMessageBehavior); }
}
protected override object CreateBehavior()
{
//how do I create an instance using the IoC container here?
}
}