Skip to content

Conversation

@jbogard
Copy link
Collaborator

@jbogard jbogard commented Jan 30, 2023

Consolidates registration and scanning into a single configuration object; Only registers extra behaviors (pre/post processor, etc.) if there are any available.

API changes

All configuration would be consolidated into a single method (instead of parameters in an overload):

public static class ServiceCollectionExtensions {
-    public static IServiceCollection AddMediatR(this IServiceCollection services, params Assembly[] assemblies)
-    public static IServiceCollection AddMediatR(this IServiceCollection services, Action<MediatRServiceConfiguration>? configuration, params Assembly[] assemblies)
-    public static IServiceCollection AddMediatR(this IServiceCollection services, IEnumerable<Assembly> assemblies, Action<MediatRServiceConfiguration>? configuration)
-    public static IServiceCollection AddMediatR(this IServiceCollection services, params Type[] handlerAssemblyMarkerTypes)
-    public static IServiceCollection AddMediatR(this IServiceCollection services, Action<MediatRServiceConfiguration>? configuration, params Type[] handlerAssemblyMarkerTypes)
-    public static IServiceCollection AddMediatR(this IServiceCollection services, IEnumerable<Type> handlerAssemblyMarkerTypes, Action<MediatRServiceConfiguration>? configuration)
+    public static IServiceCollection AddMediatR(this IServiceCollection services, Action<MediatRServiceConfiguration> configuration)
}

All the parameters are now moved to the MediatRServiceConfiguration object, including a pass-through method to add behaviors:

public class MediatRServiceConfiguration {
-    public Func<Type, bool> TypeEvaluator { get; private set; } = t => true;
-    public Type MediatorImplementationType { get; private set; }
-    public ServiceLifetime Lifetime { get; private set; }
+    public Func<Type, bool> TypeEvaluator { get; set; } = t => true;
+    public Type MediatorImplementationType { get; set; } = typeof(Mediator);
+    public ServiceLifetime Lifetime { get; set; } = ServiceLifetime.Transient;
+    public RequestExceptionActionProcessorStrategy RequestExceptionActionProcessorStrategy { get; set; } = RequestExceptionActionProcessorStrategy.ApplyForUnhandledExceptions;
+    internal List<Assembly> AssembliesToRegister { get; } = new();
+    public List<ServiceDescriptor> BehaviorsToRegister { get; } = new();

// These methods removed to instead use the properties directly
-    public MediatRServiceConfiguration Using<TMediator>() where TMediator : IMediator
-    public MediatRServiceConfiguration AsSingleton()
-    public MediatRServiceConfiguration AsScoped()
-    public MediatRServiceConfiguration AsTransient()
-    public MediatRServiceConfiguration WithEvaluator(Func<Type, bool> evaluator)

// These replace the overloads for passing in types or assemblies to scan
+    public MediatRServiceConfiguration RegisterServicesFromAssemblyContaining<T>()
+    public MediatRServiceConfiguration RegisterServicesFromAssemblyContaining(Type type)
+    public MediatRServiceConfiguration RegisterServicesFromAssembly(Assembly assembly)
+    public MediatRServiceConfiguration RegisterServicesFromAssemblies(params Assembly[] assemblies)

// These are new methods to add concrete behaviors but merely passthrough the configuration to the underlying `IServiceCollection`
+    public MediatRServiceConfiguration AddBehavior<TServiceType, TImplementationType>(ServiceLifetime serviceLifetime = ServiceLifetime.Transient)
+    public MediatRServiceConfiguration AddBehavior(Type serviceType, Type implementationType, ServiceLifetime serviceLifetime = ServiceLifetime.Transient)
// This method is for registering an open behavior still passing through the configuration
+    public MediatRServiceConfiguration AddOpenBehavior(Type openBehaviorType, ServiceLifetime serviceLifetime = ServiceLifetime.Transient)

Behavior changes

The service scanning was modified to only register with the container the "built-in" behaviors of:

  • RequestPreProcessorBehavior<,>
  • RequestPostProcessorBehavior<,>
  • RequestExceptionProcessorBehavior<,>
  • RequestExceptionActionProcessorBehavior<,>
    When "Sub-behaviors" of those types are found in the IServiceCollection.

There are performance implications to resolving those sub-behaviors, so if they don't exist, the built-in behavior won't be registered.

@jbogard jbogard changed the title Consolidate registration Consolidate registration to single configuration object and optimize registration Jan 31, 2023
@jbogard
Copy link
Collaborator Author

jbogard commented Jan 31, 2023

Fixes #829

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants