Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Castle Windsor test streams too and fix all checks
  • Loading branch information
alexandruchirita4192 authored May 17, 2022
commit 19211b34a9292ba4009e2fe964fbe7058577bf94
68 changes: 59 additions & 9 deletions samples/MediatR.Examples.Windsor/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ private static Task Main(string[] args)
var writer = new WrappingWriter(Console.Out);
var mediator = BuildMediator(writer);

return Runner.Run(mediator, writer, "Castle.Windsor");
return Runner.Run(mediator, writer, "Castle.Windsor", true);
}

private static IMediator BuildMediator(WrappingWriter writer)
Expand All @@ -29,33 +29,83 @@ private static IMediator BuildMediator(WrappingWriter writer)

// *** The default lifestyle for Windsor is Singleton
// *** If you are using ASP.net, it's better to register your services with 'Per Web Request LifeStyle'.

container.Register(Classes.FromAssemblyContaining<Ping>().BasedOn(typeof(IRequestHandler<,>)).WithServiceAllInterfaces());
container.Register(Classes.FromAssemblyContaining<Ping>().BasedOn(typeof(INotificationHandler<>)).WithServiceAllInterfaces());

var fromAssemblyContainingPing = Classes.FromAssemblyContaining<Ping>();
container.Register(fromAssemblyContainingPing.BasedOn(typeof(IRequestHandler<,>)).WithServiceAllInterfaces().AllowMultipleMatches());
container.Register(fromAssemblyContainingPing.BasedOn(typeof(INotificationHandler<>)).WithServiceAllInterfaces().AllowMultipleMatches());
container.Register(Component.For(typeof(IPipelineBehavior<,>)).ImplementedBy(typeof(RequestExceptionActionProcessorBehavior<,>)));
container.Register(Component.For(typeof(IPipelineBehavior<,>)).ImplementedBy(typeof(RequestExceptionProcessorBehavior<,>)));
container.Register(fromAssemblyContainingPing.BasedOn(typeof(IRequestExceptionHandler<,,>)).WithServiceAllInterfaces().AllowMultipleMatches());
container.Register(fromAssemblyContainingPing.BasedOn(typeof(IStreamRequestHandler<,>)).WithServiceAllInterfaces().AllowMultipleMatches());
container.Register(fromAssemblyContainingPing.BasedOn(typeof(IRequestPreProcessor<>)).WithServiceAllInterfaces().AllowMultipleMatches());
container.Register(fromAssemblyContainingPing.BasedOn(typeof(IRequestPostProcessor<,>)).WithServiceAllInterfaces().AllowMultipleMatches());

container.Register(Component.For<IMediator>().ImplementedBy<Mediator>());
container.Register(Component.For<TextWriter>().Instance(writer));
container.Register(Component.For<ServiceFactory>().UsingFactoryMethod<ServiceFactory>(k => (type =>
{
var enumerableType = type
.GetInterfaces()
.Concat(new [] {type})
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>));
.Concat(new[] { type })
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>));

var service = enumerableType?.GetGenericArguments()?[0];
var resolvedType = enumerableType != null ? k.ResolveAll(service) : k.Resolve(type);
var genericArguments = service?.GetGenericArguments();

// Handle exceptions even using the base request types
if (service == null
|| genericArguments == null
|| !service.IsInterface
|| !service.IsGenericType
|| !service.IsConstructedGenericType
|| !(service.GetGenericTypeDefinition()
?.IsAssignableTo(typeof(IRequestExceptionHandler<,,>)) ?? false)
|| genericArguments.Length != 3
|| !(genericArguments[0].BaseType?.IsClass ?? false))
{
return resolvedType;
}

var serviceFactory = k.Resolve<ServiceFactory>();
var baseRequestType = genericArguments[0].BaseType;
var response = genericArguments[1];
var exceptionType = genericArguments[2];

// Check if the base request type is valid
if (!baseRequestType.IsClass
|| baseRequestType == typeof(object)
|| ((!baseRequestType.GetInterfaces()
?.Any(i => i.IsAssignableFrom(typeof(IRequest<>)))) ?? true))
{
return resolvedType;
}

return enumerableType != null ? k.ResolveAll(enumerableType.GetGenericArguments()[0]) : k.Resolve(type);
var exceptionHandlerInterfaceType = typeof(IRequestExceptionHandler<,,>).MakeGenericType(baseRequestType, response, exceptionType);
var enumerableExceptionHandlerInterfaceType = typeof(IEnumerable<>).MakeGenericType(exceptionHandlerInterfaceType);

// This is assumed Array because this method calls ResolveAll when a IEnumerable<> is passed as argument
var firstArray = serviceFactory.Invoke(enumerableExceptionHandlerInterfaceType) as Array;
var secondArray = resolvedType is Array ? resolvedType as Array : new[] { resolvedType };
var resultArray = Array.CreateInstance(typeof(object), firstArray.Length + secondArray.Length);
Array.Copy(firstArray, resultArray, firstArray.Length);
Array.Copy(secondArray, 0, resultArray, firstArray.Length, secondArray.Length);

return resultArray;
})));

//Pipeline
container.Register(Component.For(typeof(IStreamPipelineBehavior<,>)).ImplementedBy(typeof(GenericStreamPipelineBehavior<,>)));
container.Register(Component.For(typeof(IPipelineBehavior<,>)).ImplementedBy(typeof(RequestPreProcessorBehavior<,>)).NamedAutomatically("PreProcessorBehavior"));
container.Register(Component.For(typeof(IPipelineBehavior<,>)).ImplementedBy(typeof(RequestPostProcessorBehavior<,>)).NamedAutomatically("PostProcessorBehavior"));
container.Register(Component.For(typeof(IPipelineBehavior<,>)).ImplementedBy(typeof(GenericPipelineBehavior<,>)).NamedAutomatically("Pipeline"));
container.Register(Component.For(typeof(IRequestPreProcessor<>)).ImplementedBy(typeof(GenericRequestPreProcessor<>)).NamedAutomatically("PreProcessor"));
container.Register(Component.For(typeof(IRequestPostProcessor <,>)).ImplementedBy(typeof(GenericRequestPostProcessor<,>)).NamedAutomatically("PostProcessor"));
container.Register(Component.For(typeof(IRequestPostProcessor<,>)).ImplementedBy(typeof(GenericRequestPostProcessor<,>)).NamedAutomatically("PostProcessor"));
container.Register(Component.For(typeof(IRequestPostProcessor<,>), typeof(ConstrainedRequestPostProcessor<,>)).NamedAutomatically("ConstrainedRequestPostProcessor"));
container.Register(Component.For(typeof(INotificationHandler<>), typeof(ConstrainedPingedHandler<>)).NamedAutomatically("ConstrainedPingedHandler"));

var mediator = container.Resolve<IMediator>();

return mediator;
}
}
}