【问题标题】:Implement errorhandler in WCF with IoC使用 IoC 在 WCF 中实现错误处理程序
【发布时间】:2016-01-10 20:22:44
【问题描述】:

我正在尝试按照本教程在我的 WCF 服务上实现错误处理程序: Implementing IErrorHandler 在这个错误处理程序中,我希望通过传递我的记录器,实现 ILogger(在我的情况下由 NLog 使用),将每个异常登录到日志文件中。

现在的问题是我想使用依赖注入,将记录器作为构造函数参数,由我的 IoC 容器初始化(使用 SimpleInjector)。

谁能帮我解决这个问题? (仅供参考...我对 DI 和 IoC 很陌生)

错误处理程序:

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

【问题讨论】:

  • 您能提供您的代码(服务、行为、错误处理程序、配置)吗?无论如何,这会更容易。
  • 你看到docs了吗

标签: c# wcf dependency-injection ioc-container simple-injector


【解决方案1】:

我没有完整的答案,因为我不了解温莎。我通过使用构建策略扩展使用 Unity 完成了这项工作。我认为温莎也有类似的东西。

请参阅http://www.primordialcode.com/blog/post/unity-wcf-service-resolution-container-extension/ 详细了解如何将构建策略与 WCF 一起使用。

下面是一个sn-p,我以前可以在解析之前配置服务主机。该代码支持配置和添加服务端点和行为作为接口,主机解析将通过容器解析。

请注意,我通常不使用 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;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 2014-12-01
    • 2019-06-02
    相关资源
    最近更新 更多