Skip to content

Commit 1952869

Browse files
Support for explicit assemblies configuration (where to find messages and handlers) (#202)
1 parent 920135d commit 1952869

File tree

34 files changed

+5606
-57
lines changed

34 files changed

+5606
-57
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ services.AddMediator((MediatorOptions options) =>
271271
options.ServiceLifetime = ServiceLifetime.Singleton;
272272
// Only available from v3:
273273
options.NotificationPublisherType = typeof(Mediator.ForeachAwaitPublisher);
274+
options.Assemblies = [typeof(...)];
274275
options.PipelineBehaviors = [];
275276
options.StreamPipelineBehaviors = [];
276277
});
@@ -286,9 +287,13 @@ services.AddMediator((MediatorOptions options) =>
286287
* `Transient` - mediator and handlers registered as transient
287288
* `Scoped` - mediator and handlers registered as scoped
288289
* `NotificationPublisherType` - the type used for publishing notifications (`ForeachAwaitPublisher` and `TaskWhenAllPublisher` are built in)
290+
* `Assemblies` - which assemblies the source generator should scan for messages and handlers. When not used the source generator will scan all references assemblies (same behavior as v2)
289291
* `PipelineBehaviors`/`StreamPipelineBehaviors` - ordered array of types used for the pipeline
290292
* The source generator adds DI regristrations manually as oppposed to open generics registrations, to support NativeAOT. You can also manually add pipeline behaviors to the DI container if you are not doing AoT compilation.
291293

294+
Note that since parsing of these options is done during compilation/source generation, all values must be compile time constants.
295+
In addition, since some types are not valid attributes parameter types (such as arrays/lists), some configuration is only available through `AddMediator`/`MediatorOptions` and not the assembly attribute.
296+
292297
Singleton lifetime is highly recommended as it yields the best performance.
293298
Every application is different, but it is likely that a lot of your message handlers doesn't keep state and have no need for transient or scoped lifetime.
294299
In a lot of cases those lifetimes only allocate lots of memory for no particular reason.
@@ -334,6 +339,8 @@ using var serviceProvider = services.BuildServiceProvider();
334339
### 4.3. Create `IRequest<>` type
335340

336341
```csharp
342+
services.AddMediator((MediatorOptions options) => options.Assemblies = [typeof(Ping)]);
343+
using var serviceProvider = services.BuildServiceProvider();
337344
var mediator = serviceProvider.GetRequiredService<IMediator>();
338345
var ping = new Ping(Guid.NewGuid());
339346
var pong = await mediator.Send(ping);
@@ -366,6 +373,7 @@ Pipeline behaviors currently must be added manually.
366373
```csharp
367374
services.AddMediator((MediatorOptions options) =>
368375
{
376+
options.Assemblies = [typeof(Ping)];
369377
options.PipelineBehaviors = [typeof(PingValidator)];
370378
});
371379

@@ -391,6 +399,7 @@ Message pre- and post-processors along with the exception handlers can also cons
391399
```csharp
392400
services.AddMediator((MediatorOptions options) =>
393401
{
402+
options.Assemblies = [typeof(ErrorMessage)];
394403
options.PipelineBehaviors = [typeof(ErrorLoggerHandler<,>)];
395404
});
396405

samples/Showcase/Program.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,19 @@
88

99
var services = new ServiceCollection();
1010

11-
services.AddMediator(options =>
12-
{
13-
options.NotificationPublisherType = typeof(FireAndForgetNotificationPublisher);
14-
options.PipelineBehaviors =
15-
[
16-
// Ordering of pipeline behavior registrations matter!
17-
typeof(ErrorLoggerHandler<,>),
18-
typeof(PingValidator),
19-
];
20-
});
11+
services.AddMediator(
12+
(MediatorOptions options) =>
13+
{
14+
options.Assemblies = [typeof(Ping)];
15+
options.NotificationPublisherType = typeof(FireAndForgetNotificationPublisher);
16+
options.PipelineBehaviors =
17+
[
18+
// Ordering of pipeline behavior registrations matter!
19+
typeof(ErrorLoggerHandler<,>),
20+
typeof(PingValidator),
21+
];
22+
}
23+
);
2124

2225
var sp = services.BuildServiceProvider();
2326

samples/apps/ASPNET_Core/Program.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
using ASPNETCore.WeatherForecasts;
2+
using Mediator;
3+
14
var builder = WebApplication.CreateBuilder(args);
25

36
// Add services to the container.
@@ -8,7 +11,12 @@
811
builder.Services.AddEndpointsApiExplorer();
912
builder.Services.AddSwaggerGen();
1013

11-
builder.Services.AddMediator();
14+
builder.Services.AddMediator(
15+
(MediatorOptions options) =>
16+
{
17+
options.Assemblies = [typeof(GetWeatherForecasts).Assembly];
18+
}
19+
);
1220

1321
var app = builder.Build();
1422

samples/apps/ASPNET_Core_CleanArchitecture/AspNetCoreSample.Application/ServiceCollectionExtensions.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ public static class ServiceCollectionExtensions
77
{
88
public static IServiceCollection AddApplication(this IServiceCollection services)
99
{
10-
services.AddMediator(options =>
11-
{
12-
options.ServiceLifetime = ServiceLifetime.Scoped;
13-
});
10+
services.AddMediator(
11+
(MediatorOptions options) =>
12+
{
13+
options.Assemblies = [typeof(AddTodoItem)];
14+
options.ServiceLifetime = ServiceLifetime.Scoped;
15+
}
16+
);
1417
return services
1518
.AddSingleton(typeof(IPipelineBehavior<,>), typeof(ErrorLoggingBehaviour<,>))
1619
.AddSingleton(typeof(IPipelineBehavior<,>), typeof(MessageValidatorBehaviour<,>));

samples/apps/ASPNET_Core_Indirect/AspNetCoreIndirect.Application/Program.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
using AspNetCoreIndirect.Application;
2+
using Mediator;
3+
14
var builder = WebApplication.CreateBuilder(args);
25

36
// Add services to the container.
@@ -8,7 +11,12 @@
811
builder.Services.AddEndpointsApiExplorer();
912
builder.Services.AddSwaggerGen();
1013

11-
builder.Services.AddMediator();
14+
builder.Services.AddMediator(
15+
(MediatorOptions options) =>
16+
{
17+
options.Assemblies = [typeof(GetWeatherForecast)];
18+
}
19+
);
1220

1321
var app = builder.Build();
1422

samples/apps/InternalMessages/InternalMessages.Api/Program.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
using InternalMessages.Application;
12
using InternalMessages.Domain;
3+
using Mediator;
24
using Microsoft.AspNetCore.Mvc;
35

46
var builder = WebApplication.CreateBuilder(args);
57

6-
builder.Services.AddMediator();
8+
builder.Services.AddMediator(
9+
(MediatorOptions options) =>
10+
{
11+
options.Assemblies = [typeof(Ping), typeof(PingHandler)];
12+
}
13+
);
714

815
var app = builder.Build();
916

samples/basic/Console/Program.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88

99
// This extensions method is generated, and is put in the "Microsoft.Extensions.DependencyInjection" namespace.
1010
// We override the namespace in the "MediatorOptions" object.
11-
services.AddMediator(options =>
12-
{
13-
options.Namespace = "SimpleConsole";
14-
});
11+
services.AddMediator(
12+
(MediatorOptions options) =>
13+
{
14+
options.Namespace = "SimpleConsole";
15+
options.Assemblies = [typeof(Ping)];
16+
}
17+
);
1518

1619
// Standard handlers are added by default, but we need to add pipeline steps manually.
1720
// Here are two examples.

samples/basic/ConsoleAOT/Program.cs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,20 @@
55

66
// This extensions method is generated, and is put in the "Mediator" namespace by default.
77
// We override the namespace in the "MediatorOptions" object.
8-
services.AddMediator(options =>
9-
{
10-
options.Namespace = "SimpleConsoleAOT";
11-
options.PipelineBehaviors =
12-
[
13-
// Standard handlers are added by default, but we need to add pipeline steps manually.
14-
// Here are two examples.
15-
typeof(GenericLoggerHandler<,>), // This will run 1st
16-
typeof(PingValidator), // This will run 2nd
17-
];
18-
});
8+
services.AddMediator(
9+
(MediatorOptions options) =>
10+
{
11+
options.Namespace = "SimpleConsoleAOT";
12+
options.Assemblies = [typeof(Ping)];
13+
options.PipelineBehaviors =
14+
[
15+
// Standard handlers are added by default, but we need to add pipeline steps manually.
16+
// Here are two examples.
17+
typeof(GenericLoggerHandler<,>), // This will run 1st
18+
typeof(PingValidator), // This will run 2nd
19+
];
20+
}
21+
);
1922

2023
var serviceProvider = services.BuildServiceProvider();
2124

samples/basic/NetFramework/Console/Program.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ static async Task<int> Main(string[] args)
1414

1515
// This extensions method is generated, and is put in the "Microsoft.Extensions.DependencyInjection" namespace.
1616
// We override the namespace in the "MediatorOptions" object.
17-
services.AddMediator(options =>
18-
{
19-
options.Namespace = "SimpleConsole";
20-
});
17+
services.AddMediator(
18+
(MediatorOptions options) =>
19+
{
20+
options.Namespace = "SimpleConsole";
21+
options.Assemblies = new AssemblyReference[] { typeof(Ping) };
22+
}
23+
);
2124

2225
// Standard handlers are added by default, but we need to add pipeline steps manually.
2326
// Here are two examples.

samples/basic/NotificationPublisher/Program.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77

88
var services = new ServiceCollection();
99

10-
services.AddMediator(options =>
11-
{
12-
options.NotificationPublisherType = typeof(MyNotificationPublisher);
13-
});
10+
services.AddMediator(
11+
(MediatorOptions options) =>
12+
{
13+
options.Assemblies = [typeof(Notification)];
14+
options.NotificationPublisherType = typeof(MyNotificationPublisher);
15+
}
16+
);
1417

1518
var serviceProvider = services.BuildServiceProvider();
1619

samples/basic/Notifications/Program.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66

77
var services = new ServiceCollection();
88

9-
services.AddMediator();
9+
services.AddMediator(
10+
(MediatorOptions options) =>
11+
{
12+
options.Assemblies = [typeof(Notification)];
13+
}
14+
);
1015

1116
var serviceProvider = services.BuildServiceProvider();
1217

samples/basic/Streaming/Program.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
var services = new ServiceCollection();
1010

1111
// This extensions method is generated, and is put in the "Mediator" namespace by default.
12-
services.AddMediator();
12+
services.AddMediator(
13+
(MediatorOptions options) =>
14+
{
15+
options.Assemblies = [typeof(StreamPing)];
16+
}
17+
);
1318

1419
var serviceProvider = services.BuildServiceProvider();
1520

samples/use-cases/Autofac_DI/Program.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66

77
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
88

9-
builder.Services.AddMediator(config =>
10-
{
11-
config.Namespace = "Foo.Generated";
12-
config.ServiceLifetime = ServiceLifetime.Scoped;
13-
});
9+
builder.Services.AddMediator(
10+
(MediatorOptions options) =>
11+
{
12+
options.Namespace = "Foo.Generated";
13+
options.Assemblies = [typeof(Ping)];
14+
options.ServiceLifetime = ServiceLifetime.Scoped;
15+
}
16+
);
1417

1518
var app = builder.Build();
1619

samples/use-cases/MassTransitIntegration/Program.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66

77
var builder = WebApplication.CreateBuilder(args);
88

9-
builder.Services.AddMediator((MediatorOptions options) => { });
9+
builder.Services.AddMediator(
10+
(MediatorOptions options) =>
11+
{
12+
options.Assemblies = [typeof(WeatherUpdated)];
13+
}
14+
);
1015

1116
builder.Services.AddMassTransit(options =>
1217
{

0 commit comments

Comments
 (0)