我正在尝试按照本教程在我的WCF服务上实现错误处理程序: Implementing IErrorHandler 在这个错误处理程序中,我希望每个异常都能通过传递我的记录器来登录日志文件,实现ILogger(在我的情况下由NLog使用)。
现在的问题是我想使用依赖注入,将记录器作为构造函数参数,由我的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
与教程相同,但在behaviorExtension中使用我自己的类型
的Global.asax.cs
创建SimpleInjector容器并注册类型
答案 0 :(得分:0)
我没有完整的答案,因为我不认识温莎。我通过使用构建策略扩展使用Unity完成了这项工作。我认为温莎有类似的东西。
请参阅http://www.primordialcode.com/blog/post/unity-wcf-service-resolution-container-extension/有关如何与WCF一起使用构建策略的详细信息。
以下是我以前能够在解析之前配置服务主机的代码段。该代码支持配置和添加服务端点和行为,作为通过容器解析主机解析的接口。
请注意,我通常不会使用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;
}
}
}