使用IoC在WCF中实现errorhandler
本文关键字:实现 errorhandler WCF IoC 使用 | 更新日期: 2023-09-27 18:17:19
我想在我的WCF服务上实现一个错误处理程序:实现IErrorHandler在这个errorhandler中,我希望每个异常都记录到一个日志文件中,通过传递我的记录器,实现ILogger(在我的情况下使用NLog)。
现在的问题是,我想使用依赖注入,logger作为构造函数参数,由我的IoC容器初始化(使用SimpleInjector)。
谁能帮我这个忙?(仅供参考…我是DI和IoC的新手)ErrorHandler:
public class ErrorHandler : IErrorHandler, IServiceBehavior
{
private readonly ILogger _logger;
public ErrorHandler(ILogger logger)
{
_logger = logger;
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
IErrorHandler errorHandler = new ErrorHandler(_logger);
foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
{
var channelDispatcher = channelDispatcherBase as ChannelDispatcher;
if (channelDispatcher != null)
{
channelDispatcher.ErrorHandlers.Add(errorHandler);
}
}
}
public bool HandleError(Exception error)
{
_logger.Error("EXCEPTION: ", error);
return true;
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
// Shield the unknown exception
FaultException faultException = new FaultException("Server error encountered. All details have been logged.");
MessageFault messageFault = faultException.CreateMessageFault();
fault = Message.CreateMessage(version, messageFault, faultException.Action);
}
}
ErrorHandlerElement:
public class ErrorHandlerElement : BehaviorExtensionElement
{
private readonly ILogger _logger;
public ErrorHandlerElement(ILogger logger)
{
_logger = logger;
}
protected override object CreateBehavior()
{
return new ErrorHandler(_logger);
}
public override Type BehaviorType
{
get
{
return typeof(ErrorHandler);
}
}
}
web . config
与教程相同,但在行为学扩展
中使用我自己的类型Global.asax.cs
创建SimpleInjector容器并注册类型
我不知道完整的答案,因为我不认识Windsor。我是通过使用Unity的构建策略扩展来做到这一点的。我想温莎也有类似的东西。
有关如何将构建策略与WCF一起使用的详细信息,请参阅http://www.primordialcode.com/blog/post/unity-wcf-service-resolution-container-extension/。
下面是我过去能够在解析之前配置服务主机的代码片段。该代码支持配置和添加服务端点和行为作为接口,这些接口在主机解析时将通过容器解析。
请注意,我通常不使用app.config或类似的文件。
public class WcfServiceHostBuildPlanPolicy<TInterface, TImplementation> : IBuildPlanPolicy
where TInterface : class
where TImplementation : class, TInterface
{
private class ServiceEndpoint
{
public string Address { get; set; }
public Binding Binding { get; set; }
public Type Type { get; set; }
}
private readonly List<ServiceEndpoint> endpoints;
private readonly List<Type> behaviors;
/// <summary>
/// Adds a new service behavior.
/// </summary>
public void AddBehavior<T>() where T : IServiceBehavior
{
behaviors.Add(typeof (T));
}
public void AddServiceEndpoint(Type type, string address, Binding binding)
{
endpoints.Add(new ServiceEndpoint
{
Address = address,
Binding = binding,
Type = type
});
}
public WcfServiceHostBuildPlanPolicy()
{
m_Behaviors = new List<Type>();
m_Endpoints = new List<ServiceEndpoint>();
}
public void BuildUp(IBuilderContext context)
{
if (context.Existing == null)
{
// build up dependencies
var behavior = context.NewBuildUp<DIServiceBehavior<TInterface, TImplementation>>();
// create new DIServiceHost
var serviceHost = new DIServiceHost<TInterface, TImplementation>(behavior);
// add behaviors to ServiceHost
foreach (var behaviorType in behaviors)
{
var newBehavior = context.NewBuildUp(new NamedTypeBuildKey(behaviorType)) as IServiceBehavior;
serviceHost.Description.Behaviors.Add(newBehavior);
}
// add service endpoints to ServiceHost
endpoints.ForEach(s => serviceHost.AddServiceEndpoint(s.Type, s.Binding, s.Address));
context.Existing = serviceHost;
}
}
}