使用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容器并注册类型

使用IoC在WCF中实现errorhandler

我不知道完整的答案,因为我不认识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;
        }
    }
}