-
Notifications
You must be signed in to change notification settings - Fork 116
/
Copy pathServiceCollectionExtensions.cs
61 lines (47 loc) · 2.47 KB
/
ServiceCollectionExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
namespace Masa.Contrib.Ddd.Domain;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddDomainEventBus(
this IServiceCollection services,
Action<DispatcherOptions>? options = null)
=> services.AddDomainEventBus(AppDomain.CurrentDomain.GetAssemblies(), options);
public static IServiceCollection AddDomainEventBus(
this IServiceCollection services,
Assembly[] assemblies,
Action<DispatcherOptions>? options = null)
{
if (services.Any(service => service.ImplementationType == typeof(DomainEventBusProvider)))
return services;
services.AddSingleton<DomainEventBusProvider>();
var dispatcherOptions = new DispatcherOptions(services, assemblies);
options?.Invoke(dispatcherOptions);
services.AddSingleton(typeof(IOptions<DispatcherOptions>), _ => Microsoft.Extensions.Options.Options.Create(dispatcherOptions));
if (services.All(service => service.ServiceType != typeof(IEventBus)))
throw new Exception("Please add EventBus first.");
if (services.All(service => service.ServiceType != typeof(IUnitOfWork)))
throw new Exception("Please add UoW first.");
if (services.All(service => service.ServiceType != typeof(IIntegrationEventBus)))
throw new Exception("Please add IntegrationEventBus first.");
services.CheckAggregateRootRepositories(dispatcherOptions.AllAggregateRootTypes);
foreach (var domainServiceType in dispatcherOptions.AllDomainServiceTypes)
{
services.TryAddScoped(domainServiceType);
}
services.TryAddScoped<IDomainEventBus, DomainEventBus>();
services.TryAddScoped<IDomainService, DomainService>();
return services;
}
private static void CheckAggregateRootRepositories(this IServiceCollection services, List<Type> aggregateRootRepositoryTypes)
{
foreach (var aggregateRootRepositoryType in aggregateRootRepositoryTypes)
{
var serviceType = GetServiceRepositoryType(aggregateRootRepositoryType);
if (services.All(service => service.ServiceType != serviceType))
throw new NotImplementedException($"The number of types of {serviceType.FullName} implementation class must be 1.");
}
}
private static Type GetServiceRepositoryType(Type entityType) => typeof(IRepository<>).MakeGenericType(entityType);
private class DomainEventBusProvider
{
}
}