Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fixed FACILITIES-160

Two failing tests for FACILITIES-161 are still there
  • Loading branch information...
commit 845252aba46e25228caa19f0ed9c6f31e6da7a59 1 parent b69904e
Krzysztof Koźmic kkozmic authored
1  Changes.txt
View
@@ -3,6 +3,7 @@
- implemented IOC-355 - Add a mechanism to mark constructors as unselectable for injection, much like DoNotWireAttribute is for property injection (contributed by Rory Plaire)
- implemented IOC-353 - Add Classes.FromAssemblyInThisApplication() for parity with FromAssembly class
+- fixed FACILITIES-160 - Wcf Facility doesn't support multiple IErrorHandlers
- fixed IOC-359 - Property filtering API is confusing and buggy
- fixed IOC-356 - Specifying a hook should be enough to create an implementation-less proxy
- fixed IOC-354 - Deadlock in pooled lifestyle under heavy load
4 TODO.txt
View
@@ -12,6 +12,4 @@
- nesting scopes - NOT SUPPORTED
-- change the exception thrown when creating typed factory to point out that the facility should be added to the container first, before adding the factory.
-
-- property filters can add dependency for a single property multiple times
+- change the exception thrown when creating typed factory to point out that the facility should be added to the container first, before adding the factory.
95 src/Castle.Facilities.WcfIntegration.Tests/Service/ServiceHostFixture.cs
View
@@ -34,6 +34,8 @@ namespace Castle.Facilities.WcfIntegration.Tests
using log4net.Config;
using NUnit.Framework;
+ using log4net.Core;
+
[TestFixture]
public class ServiceHostFixture
{
@@ -462,7 +464,46 @@ public void WillApplyErrorHandlersToServices()
}
catch
{
- foreach (var log in memoryAppender.GetEvents())
+ var events = memoryAppender.GetEvents();
+ Assert.AreEqual(1, events.Length);
+ foreach (var log in events)
+ {
+ Assert.AreEqual("An error has occurred", log.RenderedMessage);
+ Assert.AreEqual("Oh No!", log.ExceptionObject.Message);
+ }
+ }
+ }
+ }
+
+ [Test]
+ public void Will_apply_multiple_error_handlers_to_service()
+ {
+ using (RegisterLoggingFacility(new WindsorContainer())
+ .AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero)
+ .Register(
+ Component.For<ErrorLogger>(),
+ Component.For<ErrorLogger>().Named("other"),
+ Component.For<IOperationsEx>().ImplementedBy<Operations>()
+ .DependsOn(new { number = 42 })
+ .AsWcfService(new DefaultServiceModel().AddEndpoints(
+ WcfEndpoint.BoundTo(new NetTcpBinding { PortSharingEnabled = true })
+ .At("net.tcp://localhost/Operations"))
+ )
+ ))
+ {
+ var client = ChannelFactory<IOperationsEx>.CreateChannel(
+ new NetTcpBinding { PortSharingEnabled = true }, new EndpointAddress("net.tcp://localhost/Operations"));
+
+ try
+ {
+ client.ThrowException();
+ Assert.Fail("Should have raised an exception");
+ }
+ catch
+ {
+ var events = memoryAppender.GetEvents();
+ Assert.AreEqual(2, events.Length);
+ foreach (var log in events)
{
Assert.AreEqual("An error has occurred", log.RenderedMessage);
Assert.AreEqual("Oh No!", log.ExceptionObject.Message);
@@ -529,7 +570,49 @@ public void WillApplyErrorHandlersToServicesExplicitly()
}
catch
{
- foreach (var log in memoryAppender.GetEvents())
+ var events = memoryAppender.GetEvents();
+ Assert.AreEqual(1, events.Length);
+ foreach (var log in events)
+ {
+ Assert.AreEqual("An error has occurred", log.RenderedMessage);
+ Assert.AreEqual("Oh No!", log.ExceptionObject.Message);
+ }
+ }
+ }
+ }
+
+ [Test]
+ public void Will_apply_multiple_error_handlers_to_service_explicitly()
+ {
+ using (RegisterLoggingFacility(new WindsorContainer())
+ .AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero)
+ .Register(
+ Component.For<ErrorLogger>()
+ .Attribute("scope").Eq(WcfExtensionScope.Explicit),
+ Component.For<ErrorLogger>().Named("other")
+ .Attribute("scope").Eq(WcfExtensionScope.Explicit),
+ Component.For<IOperationsEx>().ImplementedBy<Operations>()
+ .DependsOn(new { number = 42 })
+ .AsWcfService(new DefaultServiceModel().AddEndpoints(
+ WcfEndpoint.BoundTo(new NetTcpBinding { PortSharingEnabled = true })
+ .At("net.tcp://localhost/Operations"))
+ .AddExtensions(typeof(ErrorLogger), "other")
+ )
+ ))
+ {
+ var client = ChannelFactory<IOperationsEx>.CreateChannel(
+ new NetTcpBinding { PortSharingEnabled = true }, new EndpointAddress("net.tcp://localhost/Operations"));
+
+ try
+ {
+ client.ThrowException();
+ Assert.Fail("Should have raised an exception");
+ }
+ catch
+ {
+ var events = memoryAppender.GetEvents();
+ Assert.AreEqual(2, events.Length);
+ foreach (var log in events)
{
Assert.AreEqual("An error has occurred", log.RenderedMessage);
Assert.AreEqual("Oh No!", log.ExceptionObject.Message);
@@ -546,12 +629,14 @@ public void WillApplyErrorHandlersToEndpointsExplicitly()
.Register(
Component.For<ErrorLogger>()
.Attribute("scope").Eq(WcfExtensionScope.Explicit),
+ Component.For<ErrorLogger>().Named("other")
+ .Attribute("scope").Eq(WcfExtensionScope.Explicit),
Component.For<IOperationsEx>().ImplementedBy<Operations>()
.DependsOn(new { number = 42 })
.AsWcfService(new DefaultServiceModel().AddEndpoints(
WcfEndpoint.BoundTo(new NetTcpBinding { PortSharingEnabled = true })
.At("net.tcp://localhost/Operations")
- .AddExtensions(typeof(ErrorLogger)))
+ .AddExtensions(typeof(ErrorLogger), "other"))
)
))
{
@@ -565,7 +650,9 @@ public void WillApplyErrorHandlersToEndpointsExplicitly()
}
catch
{
- foreach (var log in memoryAppender.GetEvents())
+ var events = memoryAppender.GetEvents();
+ Assert.AreEqual(2, events.Length);
+ foreach (var log in events)
{
Assert.AreEqual("An error has occurred", log.RenderedMessage);
Assert.AreEqual("Oh No!", log.ExceptionObject.Message);
62 src/Castle.Facilities.WcfIntegration/Behaviors/Errors/WcfErrorBehavior.cs
View
@@ -1,4 +1,4 @@
-// Copyright 2004-2011 Castle Project - http://www.castleproject.org/
+// Copyright 2004-2012 Castle Project - http://www.castleproject.org/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
namespace Castle.Facilities.WcfIntegration
{
+ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ServiceModel;
using System.ServiceModel.Channels;
@@ -22,55 +23,74 @@ namespace Castle.Facilities.WcfIntegration
public class WcfErrorBehavior : IServiceBehavior, IEndpointBehavior
{
- private readonly IErrorHandler errorHandler;
+ private readonly ICollection<IErrorHandler> errorHandlers;
- public WcfErrorBehavior(IErrorHandler errorHandler)
+ public WcfErrorBehavior(ICollection<IErrorHandler> errorHandlers)
{
- this.errorHandler = errorHandler;
+ this.errorHandlers = errorHandlers;
}
- #region IServiceBehavior
-
- public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
- Collection<ServiceEndpoint> endpoints,
- BindingParameterCollection bindingParameters)
+ public WcfErrorBehavior(params IErrorHandler[] errorHandlers)
{
+ this.errorHandlers = new List<IErrorHandler>(errorHandlers);
}
- public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
+ public void Add(IEnumerable<IErrorHandler> handlers)
{
- foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
+ foreach (var handler in handlers)
{
- channelDispatcher.ErrorHandlers.Add(errorHandler);
+ errorHandlers.Add(handler);
}
}
- public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
+ public void Add(IErrorHandler handler)
{
+ errorHandlers.Add(handler);
}
- #endregion
-
- #region IEndpointBehavior
-
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
- clientRuntime.CallbackDispatchRuntime.ChannelDispatcher.ErrorHandlers.Add(errorHandler);
+ foreach (var errorHandler in errorHandlers)
+ {
+ clientRuntime.CallbackDispatchRuntime.ChannelDispatcher.ErrorHandlers.Add(errorHandler);
+ }
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
- endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(errorHandler);
+ foreach (var errorHandler in errorHandlers)
+ {
+ endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(errorHandler);
+ }
}
public void Validate(ServiceEndpoint endpoint)
{
}
- #endregion
+ public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
+ Collection<ServiceEndpoint> endpoints,
+ BindingParameterCollection bindingParameters)
+ {
+ }
+
+ public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
+ {
+ foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
+ {
+ foreach (var errorHandler in errorHandlers)
+ {
+ channelDispatcher.ErrorHandlers.Add(errorHandler);
+ }
+ }
+ }
+
+ public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
+ {
+ }
}
-}
+}
13 src/Castle.Facilities.WcfIntegration/Behaviors/WcfServiceExtensions.cs
View
@@ -51,7 +51,7 @@ private static void AddServiceBehaviors(ServiceHost serviceHost, IKernel kernel,
WcfUtils.AddBehaviors(kernel, WcfExtensionScope.Services,
serviceHost.Description.Behaviors, burden, behavior =>
{
- if (behavior.GetType() == typeof(ServiceBehaviorAttribute))
+ if (behavior is ServiceBehaviorAttribute)
{
serviceHost.Description.Behaviors.Remove<ServiceBehaviorAttribute>();
}
@@ -59,7 +59,7 @@ private static void AddServiceBehaviors(ServiceHost serviceHost, IKernel kernel,
{
serviceHost.Description.Behaviors.Remove<ServiceDebugBehavior>();
}
- else if (behavior.GetType() == typeof(AspNetCompatibilityRequirementsAttribute))
+ else if (behavior is AspNetCompatibilityRequirementsAttribute)
{
serviceHost.Description.Behaviors.Remove<AspNetCompatibilityRequirementsAttribute>();
}
@@ -88,9 +88,12 @@ private static void AddServiceHostExtensions(ServiceHost serviceHost, IKernel ke
private static void AddErrorHandlers(ServiceHost serviceHost, IKernel kernel, IWcfBurden burden)
{
- var errorHandlers = new KeyedByTypeCollection<IErrorHandler>();
- WcfUtils.AddBehaviors(kernel, WcfExtensionScope.Services, errorHandlers, burden, errorHandler =>
- WcfUtils.RegisterErrorHandler(serviceHost, errorHandler, true));
+ var errorHandlers = new List<IErrorHandler>();
+ WcfUtils.AddBehaviors(kernel, WcfExtensionScope.Services, errorHandlers, burden, errorHandler => WcfUtils.IsBehaviorExtension(errorHandler) == false);
+ if(errorHandlers.Count > 0)
+ {
+ WcfUtils.RegisterErrorHandlers(serviceHost, errorHandlers);
+ }
}
}
}
32 src/Castle.Facilities.WcfIntegration/Internal/WcfUtils.cs
View
@@ -82,7 +82,7 @@ public static WcfExtensionScope GetScope(ComponentModel model)
}
internal static void AddBehaviors<T>(IKernel kernel, WcfExtensionScope scope,
- KeyedByTypeCollection<T> behaviors, IWcfBurden burden,
+ ICollection<T> behaviors, IWcfBurden burden,
Predicate<T> predicate)
{
foreach (var handler in FindExtensions<T>(kernel, scope))
@@ -225,14 +225,27 @@ public static void BindChannelFactoryAware(ChannelFactory channelFactory, IChann
public static bool RegisterErrorHandler(ServiceHost serviceHost, IErrorHandler errorHandler, bool skipPiggybacks)
{
if (skipPiggybacks && IsBehaviorExtension(errorHandler)) return false;
- serviceHost.Description.Behaviors.Add(new WcfErrorBehavior(errorHandler));
+ AddErrorHandler(serviceHost.Description.Behaviors, new List<IErrorHandler> { errorHandler });
return true;
}
+ public static void RegisterErrorHandlers(ServiceHost serviceHost, ICollection<IErrorHandler> errorHandlers)
+ {
+ AddErrorHandler(serviceHost.Description.Behaviors, errorHandlers);
+ }
+
public static bool RegisterErrorHandler(ServiceEndpoint endpoint, IErrorHandler errorHandler, bool skipPiggybacks)
{
if (skipPiggybacks && IsBehaviorExtension(errorHandler)) return false;
- endpoint.Behaviors.Add(new WcfErrorBehavior(errorHandler));
+ var wcfErrorBehavior = endpoint.Behaviors.Find<WcfErrorBehavior>();
+ if (wcfErrorBehavior == null)
+ {
+ endpoint.Behaviors.Add(new WcfErrorBehavior(errorHandler));
+ }
+ else
+ {
+ wcfErrorBehavior.Add(errorHandler);
+ }
return true;
}
@@ -362,6 +375,19 @@ public static Type GetClosedGenericDefinition(Type openGenericDefinition, Type i
return updatedCache ?? getCache;
}
+ private static void AddErrorHandler(KeyedByTypeCollection<IServiceBehavior> behaviors, ICollection<IErrorHandler> errorHandlers)
+ {
+ var wcfErrorBehavior = behaviors.Find<WcfErrorBehavior>();
+ if (wcfErrorBehavior == null)
+ {
+ behaviors.Add(new WcfErrorBehavior(errorHandlers));
+ }
+ else
+ {
+ wcfErrorBehavior.Add(errorHandlers);
+ }
+ }
+
/// <summary>
/// Checks if given <paramref name="type"/> <c>Foo</c> implements <c>IExtensibleObject&lt;Foo&gt;</c>
/// </summary>
Please sign in to comment.
Something went wrong with that request. Please try again.