├── ICommand.cs ├── IQuery.cs ├── ICommandHandler.cs ├── IEventHandler.cs ├── EventTrigger.cs ├── EventMediator.cs └── EventDIExtensions.cs /ICommand.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace DDD.ApplicationLayer 3 | { 4 | public interface ICommand 5 | { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /IQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DDD.ApplicationLayer 7 | { 8 | public interface IQuery 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ICommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace DDD.ApplicationLayer 4 | { 5 | public interface ICommandHandler 6 | { 7 | } 8 | public interface ICommandHandler: ICommandHandler 9 | where T : ICommand 10 | { 11 | Task HandleAsync(T command); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /IEventHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using DDD.DomainLayer; 3 | 4 | namespace DDD.ApplicationLayer 5 | { 6 | public interface IEventHandler 7 | { 8 | } 9 | public interface IEventHandler: IEventHandler 10 | where T : IEventNotification 11 | { 12 | Task HandleAsync(T ev); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /EventTrigger.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using DDD.DomainLayer; 4 | 5 | namespace DDD.ApplicationLayer 6 | { 7 | public class EventTrigger 8 | where T : IEventNotification 9 | { 10 | private IEnumerable> handlers; 11 | public EventTrigger(IEnumerable> handlers) 12 | { 13 | this.handlers = handlers; 14 | } 15 | public async Task Trigger(T ev) 16 | { 17 | foreach (var handler in handlers) 18 | await handler.HandleAsync(ev); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /EventMediator.cs: -------------------------------------------------------------------------------- 1 | using DDD.DomainLayer; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace DDD.ApplicationLayer 8 | { 9 | public class EventMediator : IEventMediator 10 | { 11 | IServiceProvider services; 12 | public EventMediator(IServiceProvider services) 13 | { 14 | this.services = services; 15 | } 16 | public async Task TriggerEvents(IEnumerable events) 17 | { 18 | if (events == null) return; 19 | foreach(var ev in events) 20 | { 21 | var triggerType = typeof(EventTrigger<>).MakeGenericType(ev.GetType()); 22 | var trigger = services.GetService(triggerType); 23 | var task = (Task)triggerType.GetMethod(nameof(EventTrigger.Trigger)) 24 | .Invoke(trigger, new object[] { ev }); 25 | await task.ConfigureAwait(false); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /EventDIExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using DDD.DomainLayer; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.Extensions.DependencyInjection.Extensions; 8 | 9 | namespace DDD.ApplicationLayer 10 | { 11 | public static class EventDIExtensions 12 | { 13 | public static IServiceCollection AddEventHandler 14 | (this IServiceCollection services) 15 | where T : IEventNotification 16 | where H : class, IEventHandler 17 | { 18 | services.TryAddScoped(typeof(EventTrigger<>)); 19 | services.AddScoped, H>(); 20 | 21 | return services; 22 | } 23 | public static IServiceCollection AddEventMediator(this IServiceCollection service) 24 | { 25 | service.AddTransient(); 26 | return service; 27 | } 28 | public static IServiceCollection AddAllEventHandlers 29 | (this IServiceCollection service, Assembly assembly) 30 | { 31 | var method=typeof(EventDIExtensions).GetMethod("AddEventHandler", 32 | BindingFlags.Static | BindingFlags.Public); 33 | 34 | var handlers=assembly.GetTypes() 35 | .Where(x => !x.IsAbstract && x.IsClass 36 | && typeof(IEventHandler).IsAssignableFrom(x)); 37 | foreach(var handler in handlers) 38 | { 39 | var handlerInterface = handler.GetInterfaces() 40 | .Where(i => i.IsGenericType && typeof(IEventHandler).IsAssignableFrom(i)) 41 | .SingleOrDefault(); 42 | if(handlerInterface != null) 43 | { 44 | var eventType = handlerInterface.GetGenericArguments()[0]; 45 | method.MakeGenericMethod(new Type[] { eventType, handler }) 46 | .Invoke(null, new object[] { service }); 47 | } 48 | } 49 | service.AddEventMediator(); 50 | return service; 51 | } 52 | public static IServiceCollection AddAllCommandHandlers 53 | (this IServiceCollection service, Assembly assembly) 54 | { 55 | var handlers = assembly.GetTypes() 56 | .Where(x => !x.IsAbstract && x.IsClass 57 | && typeof(ICommandHandler).IsAssignableFrom(x)); 58 | foreach (var handler in handlers) 59 | { 60 | var handlerInterface = handler.GetInterfaces() 61 | .Where(i => i.IsGenericType && typeof(ICommandHandler).IsAssignableFrom(i)) 62 | .SingleOrDefault(); 63 | if (handlerInterface != null) 64 | { 65 | service.AddScoped(handlerInterface, handler); 66 | } 67 | } 68 | return service; 69 | } 70 | public static IServiceCollection AddAllQueries 71 | (this IServiceCollection service, Assembly assembly) 72 | { 73 | var queries = assembly.GetTypes() 74 | .Where(x => !x.IsAbstract && x.IsClass 75 | && typeof(IQuery).IsAssignableFrom(x)); 76 | foreach (var query in queries) 77 | { 78 | var queryInterface = query.GetInterfaces() 79 | .Where(i => !i.IsGenericType && typeof(IQuery) != i && 80 | typeof(IQuery).IsAssignableFrom(i)) 81 | .SingleOrDefault(); 82 | if (queryInterface != null) 83 | { 84 | service.AddTransient(queryInterface, query); 85 | } 86 | } 87 | return service; 88 | } 89 | } 90 | } 91 | --------------------------------------------------------------------------------