wcf – 将依赖项注入到IErrorHandler实现中
|
我正在实现IErrorHandler,以便将WCF服务的所有错误处理集中在一个位置.这样做相当好: public class ServiceErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
// ..Log..
}
public void ProvideFault(Exception error,MessageVersion version,ref Message fault)
{
// ..Provide fault..
}
}
现在,我们正在使用Ninject在服务的其余部分注入依赖关系,我也想在这里做同样的事情.由于WCF正在根据我的配置构建对象,我不认为我有任何钩子到这个过程,我需要使用属性注入: [Inject]
public ILoggingService Logger { get; set; }
然而,这似乎从来没有被注入.我尝试使用Ninject的MVC扩展来设置ServiceErrorHandler以允许像过滤器那样进行注入,但是似乎并没有这样做.有没有办法让这种情况发生? 迟到的答案,但您可以通过创建您的自定义ServiceHost注入依赖关系,假设TestServiceHost.在您的TestServiceHost中,您需要做: >使用IErrorHandler参数实现构造函数. *这个想法来自于Juval Lowy的例子 – “编程WCF服务”.有关故障和错误扩展的更多信息,您可以在那里找到. 这是工作的主机控制台应用程序.我不使用IoC,只有Pure DI,但是您可以轻松地解决任何想要的IoC的记录器: using System;
using System.Collections.ObjectModel;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
namespace ConsoleHost
{
class Program
{
static void Main(string[] args)
{
var logger = new DummyLogger();
var errorHandler = new TestErrorHandler(logger);
ServiceHost host = new TestServiceHost(errorHandler,typeof(TestService),new Uri("net.tcp://localhost:8002"));
host.Open();
Console.WriteLine("Press enter to exit");
Console.ReadKey();
}
}
[ServiceContract]
public interface ITestService
{
[OperationContract]
string Test(int input);
}
public class TestService : ITestService
{
public string Test(int input)
{
throw new Exception("Test exception!");
}
}
public class TestErrorHandler : IErrorHandler
{
private ILogger Logger { get; }
public TestErrorHandler(ILogger logger)
{
Logger = logger;
}
public bool HandleError(Exception error)
{
Logger.Log(error.Message);
return true;
}
public void ProvideFault(Exception error,ref Message fault)
{
FaultException fe = new FaultException();
MessageFault message = fe.CreateMessageFault();
fault = Message.CreateMessage(version,message,null);
}
}
public class TestServiceHost : ServiceHost
{
private readonly IErrorHandler errorHandler;
public TestServiceHost(IErrorHandler errorHandler,Type serviceType,params Uri[] baseAddresses)
: base(serviceType,baseAddresses)
{
this.errorHandler = errorHandler;
}
protected override void OnOpening()
{
Description.Behaviors.Add(new ErrorHandlerBehaviour(errorHandler));
base.OnOpening();
}
class ErrorHandlerBehaviour : IServiceBehavior,IErrorHandler
{
private readonly IErrorHandler errorHandler;
public ErrorHandlerBehaviour(IErrorHandler errorHandler)
{
this.errorHandler = errorHandler;
}
bool IErrorHandler.HandleError(Exception error)
{
return errorHandler.HandleError(error);
}
void IErrorHandler.ProvideFault(Exception error,ref Message fault)
{
errorHandler.ProvideFault(error,version,ref fault);
}
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription,ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
{
channelDispatcher.ErrorHandlers.Add(this);
}
}
void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription,ServiceHostBase serviceHostBase,Collection<ServiceEndpoint> endpoints,BindingParameterCollection bindingParameters)
{
}
void IServiceBehavior.Validate(ServiceDescription serviceDescription,ServiceHostBase serviceHostBase)
{
}
}
}
// Dummy logger
public interface ILogger
{
void Log(string input);
}
public class DummyLogger : ILogger
{
public void Log(string input) => Console.WriteLine(input);
}
}
配置: <system.serviceModel>
<services>
<service name="ConsoleHost.TestService">
<endpoint address="net.tcp://localhost:8002/TestService"
binding="netTcpBinding"
contract="ConsoleHost.ITestService" />
</service>
</services>
</system.serviceModel>
顺便说一句.确保你添加了System.Runtime.Serialization到你的引用 (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
