CQRS_Simple/CQRS_Simple.API/Modules/MediatorModule.cs
2022-04-07 14:00:58 +08:00

84 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Autofac;
using Autofac.Core;
using Autofac.Features.Variance;
using CQRS_Simple.API.PipelineBehaviors;
using FluentValidation;
using MediatR;
using MediatR.Pipeline;
namespace CQRS_Simple.API.Modules
{
public class MediatorModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterSource(new ScopedContravariantRegistrationSource(
typeof(IRequestHandler<,>),
typeof(INotificationHandler<>),
typeof(IValidator<>)
));
builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly).AsImplementedInterfaces();
var mediatrOpenTypes = new[] { typeof(IRequestHandler<,>), typeof(INotificationHandler<>), typeof(IValidator<>), };
foreach (var mediatrOpenType in mediatrOpenTypes)
{
builder
.RegisterAssemblyTypes(typeof(Startup).GetTypeInfo().Assembly)
.AsClosedTypesOf(mediatrOpenType)
.AsImplementedInterfaces();
}
builder.RegisterGeneric(typeof(RequestPostProcessorBehavior<,>)).As(typeof(IPipelineBehavior<,>));
builder.RegisterGeneric(typeof(RequestPreProcessorBehavior<,>)).As(typeof(IPipelineBehavior<,>));
//Mediator validation Pipeline
builder.RegisterGeneric(typeof(ValidationBehavior<,>)).As(typeof(IPipelineBehavior<,>));
builder.Register<ServiceFactory>(ctx =>
{
var c = ctx.Resolve<IComponentContext>();
return t => c.Resolve(t);
});
// builder.RegisterGeneric(typeof(CommandValidationBehavior<,>)).As(typeof(IPipelineBehavior<,>));
}
public class ScopedContravariantRegistrationSource : IRegistrationSource
{
private readonly IRegistrationSource _source = new ContravariantRegistrationSource();
private readonly List<Type> _types = new List<Type>();
public ScopedContravariantRegistrationSource(params Type[] types)
{
if (types == null)
throw new ArgumentNullException(nameof(types));
if (!types.All(x => x.IsGenericTypeDefinition))
throw new ArgumentException("Supplied types should be generic type definitions");
_types.AddRange(types);
}
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<ServiceRegistration>> registrationAccessor)
{
var components = _source.RegistrationsFor(service, registrationAccessor);
foreach (var c in components)
{
var defs = c.Target.Services
.OfType<TypedService>()
.Select(x => x.ServiceType.GetGenericTypeDefinition());
if (defs.Any(_types.Contains))
yield return c;
}
}
public bool IsAdapterForIndividualComponents => _source.IsAdapterForIndividualComponents;
}
}
}