Skip to content
This repository was archived by the owner on Feb 15, 2023. It is now read-only.

Commit a8160b8

Browse files
authored
Merge pull request #77 from remcoros/TryAdd
Use TryAdd vs Add to allow multiple calls to AddMediatr(..)
2 parents 127830d + 22f463f commit a8160b8

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

src/MediatR.Extensions.Microsoft.DependencyInjection/Registration/ServiceRegistrar.cs

+27-6
Original file line numberDiff line numberDiff line change
@@ -215,12 +215,33 @@ private static void Fill<T>(this IList<T> list, T value)
215215

216216
public static void AddRequiredServices(IServiceCollection services, MediatRServiceConfiguration serviceConfiguration)
217217
{
218-
services.AddTransient<ServiceFactory>(p => p.GetService);
219-
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPreProcessorBehavior<,>));
220-
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPostProcessorBehavior<,>));
221-
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestExceptionActionProcessorBehavior<,>));
222-
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestExceptionProcessorBehavior<,>));
223-
services.Add(new ServiceDescriptor(typeof(IMediator), serviceConfiguration.MediatorImplementationType, serviceConfiguration.Lifetime));
218+
// Use TryAdd, so any existing ServiceFactory/IMediator registration doesn't get overriden
219+
services.TryAddTransient<ServiceFactory>(p => p.GetService);
220+
services.TryAdd(new ServiceDescriptor(typeof(IMediator), serviceConfiguration.MediatorImplementationType, serviceConfiguration.Lifetime));
221+
222+
// Use TryAddTransientExact (see below), we dó want to register our Pre/Post processor behavior, even if (a more concrete)
223+
// registration for IPipelineBehavior<,> already exists. But only once.
224+
services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestPreProcessorBehavior<,>));
225+
services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestPostProcessorBehavior<,>));
226+
services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestExceptionActionProcessorBehavior<,>));
227+
services.TryAddTransientExact(typeof(IPipelineBehavior<,>), typeof(RequestExceptionProcessorBehavior<,>));
228+
}
229+
230+
/// <summary>
231+
/// Adds a new transient registration to the service collection only when no existing registration of the same service type and implementation type exists.
232+
/// In contrast to TryAddTransient, which only checks the service type.
233+
/// </summary>
234+
/// <param name="services">The service collection</param>
235+
/// <param name="serviceType">Service type</param>
236+
/// <param name="implementationType">Implementation type</param>
237+
private static void TryAddTransientExact(this IServiceCollection services, Type serviceType, Type implementationType)
238+
{
239+
if (services.Any(reg => reg.ServiceType == serviceType && reg.ImplementationType == implementationType))
240+
{
241+
return;
242+
}
243+
244+
services.AddTransient(serviceType, implementationType);
224245
}
225246
}
226247
}

test/MediatR.Extensions.Microsoft.DependencyInjection.Tests/CustomMediatorTests.cs

+15
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,20 @@ public void ShouldResolveNotificationHandlers()
3737
{
3838
_provider.GetServices<INotificationHandler<Pinged>>().Count().ShouldBe(3);
3939
}
40+
41+
[Fact]
42+
public void Can_Call_AddMediatr_multiple_times()
43+
{
44+
IServiceCollection services = new ServiceCollection();
45+
services.AddSingleton(new Logger());
46+
services.AddMediatR(cfg => cfg.Using<MyCustomMediator>(), typeof(CustomMediatorTests));
47+
48+
// Call AddMediatr again, this should NOT override our custom mediatr (With MS DI, last registration wins)
49+
services.AddMediatR(typeof(CustomMediatorTests));
50+
51+
var provider = services.BuildServiceProvider();
52+
var mediator = provider.GetRequiredService<IMediator>();
53+
mediator.GetType().ShouldBe(typeof(MyCustomMediator));
54+
}
4055
}
4156
}

0 commit comments

Comments
 (0)