gpt4 book ai didi

c# - WCF 自定义行为的依赖注入(inject)

转载 作者:可可西里 更新时间:2023-11-01 08:12:22 26 4
gpt4 key购买 nike

在我的 WCF 服务中,我有一个自定义消息检查器,用于根据 XML 模式将传入消息验证为原始 XML。消息检查器有一些它需要的依赖项(例如记录器和 XML 模式集合)。我的问题是,我可以使用依赖注入(inject)框架(我目前正在使用 Ninject)来实例化这些自定义行为并自动注入(inject)依赖项吗?

我做了一个简单的例子来演示这个概念:

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) { }
}

如何将 ILogger 注入(inject) LogMessageInspector 并将 LogMessageInspector 注入(inject) LogMessageBehavior

第二个问题,这是不是矫枉过正了?

编辑:如果我在代码中构建我的服务,我可以让它工作,因为我使用 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();
}
}

这工作正常,但我不知道如何在通过我的 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?
}
}

最佳答案

How can I go about injecting an ILogger into LogMessageInspector and a LogMessageInspector into LogMessageBehavior?

方法已经描述here

更新

如果我错了请纠正我,但我想问题归结为如何在 BehaviorExtensionElement.CreateBehavior 中获得 Ninject 内核的实例?答案取决于您的托管方案。如果托管在 IIS 下,您可以将类似这样的内容添加到您的 NinjectWebCommon:

public static StandardKernel Kernel
{
get { return (StandardKernel)bootstrapper.Kernel; }
}

由于您似乎是自托管的,因此您可能也想使用内核的静态实例。然而,在我看来,这不是一个非常好的主意。

我实际上会投票支持您自己的方法并以编程方式配置行为,除非 BehaviorExtensionElement 是必需的,因为您需要能够通过配置文件配置行为。

is this overkill?

这取决于情况,但如果您要对实现进行单元测试则绝对不是。

关于c# - WCF 自定义行为的依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13541213/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com