Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consolidate registration to single configuration object and optimize registration #828

Merged
merged 2 commits into from
Feb 6, 2023

Conversation

jbogard
Copy link
Owner

@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
Owner 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.

2 participants