public FindRunHandlers(IServiceProvider serviceProvider, ILogger logger, IGenericEventRunnerConfig config)
        {
            _serviceProvider = serviceProvider;
            _logger          = logger;
            _config          = config;

            _findHandlers = new FindHandlers(serviceProvider, logger);
        }
Beispiel #2
0
        /// <summary>
        /// This register the Generic EventRunner and the various event handlers you have created in the assemblies you provide.
        /// </summary>
        /// <param name="services"></param>
        /// <param name="config">A GenericEventRunnerConfig instance with your own settings.</param>
        /// <param name="assembliesToScan">Series of assemblies to scan. If not provided then scans the calling assembly</param>
        public static void RegisterGenericEventRunner(this IServiceCollection services,
                                                      IGenericEventRunnerConfig config,
                                                      params Assembly[] assembliesToScan)
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            if (!assembliesToScan.Any())
            {
                assembliesToScan = new Assembly[] { Assembly.GetCallingAssembly() }
            }
            ;

            var eventHandlersToRegister    = new List <(Type classType, Type interfaceType)>();
            var someAfterSaveHandlersFound = false;

            foreach (var assembly in assembliesToScan)
            {
                eventHandlersToRegister.AddRange(ClassesWithGivenEventHandlerType(typeof(IBeforeSaveEventHandler <>), assembly));
                var count = eventHandlersToRegister.Count;
                if (!config.NotUsingAfterSaveHandlers)
                {
                    eventHandlersToRegister
                    .AddRange(ClassesWithGivenEventHandlerType(typeof(IAfterSaveEventHandler <>), assembly));
                }

                someAfterSaveHandlersFound |= (eventHandlersToRegister.Count > count);
            }

            if (!someAfterSaveHandlersFound)
            {
                config.NotUsingAfterSaveHandlers = true;
            }

            foreach (var(implementationType, interfaceType) in eventHandlersToRegister)
            {
                var attr     = implementationType.GetCustomAttribute <EventHandlerConfigAttribute>();
                var lifeTime = attr?.HandlerLifetime ?? ServiceLifetime.Transient;
                if (lifeTime == ServiceLifetime.Transient)
                {
                    services.AddTransient(interfaceType, implementationType);
                }
                else if (lifeTime == ServiceLifetime.Scoped)
                {
                    services.AddScoped(interfaceType, implementationType);
                }
                else
                {
                    services.AddSingleton(interfaceType, implementationType);
                }
            }

            services.AddSingleton <IGenericEventRunnerConfig>(config);
            services.AddScoped <IEventsRunner, EventsRunner>();
        }
Beispiel #3
0
 /// <summary>
 /// This is the class that will manage the events inside your DbContext
 /// </summary>
 /// <param name="serviceProvider"></param>
 /// <param name="logger"></param>
 /// <param name="config"></param>
 public EventsRunner(IServiceProvider serviceProvider, ILogger <EventsRunner> logger, IGenericEventRunnerConfig config)
 {
     _config          = config ?? throw new ArgumentNullException(nameof(config));
     _findRunHandlers = new FindRunHandlers(serviceProvider, logger, _config);
 }
        /// <summary>
        /// This register the Generic EventRunner and the various event handlers you have created in the assemblies you provide.
        /// </summary>
        /// <param name="services"></param>
        /// <param name="config">A GenericEventRunnerConfig instance with your own settings.</param>
        /// <param name="assembliesToScan">Series of assemblies to scan. If not provided then scans the calling assembly</param>
        /// <returns>List of what it registered - useful for debugging</returns>
        public static List <string> RegisterGenericEventRunner(this IServiceCollection services,
                                                               IGenericEventRunnerConfig config,
                                                               params Assembly[] assembliesToScan)
        {
            var debugLogs = new List <string>();

            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            if (!assembliesToScan.Any())
            {
                assembliesToScan = new Assembly[] { Assembly.GetCallingAssembly() };
                debugLogs.Add("No assemblies provided so only scanning calling assembly.");
            }

            var someDuringSaveHandlersFound = false;
            var someAfterSaveHandlersFound  = false;

            foreach (var assembly in assembliesToScan)
            {
                debugLogs.Add($"Starting scanning assembly {assembly.GetName().Name} for event handlers.");
                services.RegisterHandlersIfNotAlreadyRegistered(debugLogs,
                                                                typeof(IBeforeSaveEventHandler <>), assembly);
                services.RegisterHandlersIfNotAlreadyRegistered(debugLogs,
                                                                typeof(IBeforeSaveEventHandlerAsync <>), assembly);

                if (!config.NotUsingDuringSaveHandlers)
                {
                    someDuringSaveHandlersFound |= services.RegisterHandlersIfNotAlreadyRegistered(debugLogs,
                                                                                                   typeof(IDuringSaveEventHandler <>), assembly);
                    someDuringSaveHandlersFound |= services.RegisterHandlersIfNotAlreadyRegistered(debugLogs,
                                                                                                   typeof(IDuringSaveEventHandlerAsync <>), assembly);
                }

                if (!config.NotUsingAfterSaveHandlers)
                {
                    someAfterSaveHandlersFound |= services.RegisterHandlersIfNotAlreadyRegistered(debugLogs,
                                                                                                  typeof(IAfterSaveEventHandler <>), assembly);
                    someAfterSaveHandlersFound |= services.RegisterHandlersIfNotAlreadyRegistered(debugLogs,
                                                                                                  typeof(IAfterSaveEventHandlerAsync <>), assembly);
                }
            }

            if (!someDuringSaveHandlersFound)
            {
                debugLogs.Add(config.NotUsingDuringSaveHandlers
                    ? "You manually turned off During event handlers."
                    : "No During event handlers were found, so turned that part off.");

                config.NotUsingDuringSaveHandlers = true;
            }
            if (!someAfterSaveHandlersFound)
            {
                debugLogs.Add(config.NotUsingAfterSaveHandlers
                    ? "You manually turned off After event handlers."
                    : "No After event handlers were found, so turned that part off.");

                config.NotUsingAfterSaveHandlers = true;
            }

            if (services.Contains(new ServiceDescriptor(typeof(IEventsRunner), typeof(EventsRunner), ServiceLifetime.Transient),
                                  new ServiceDescriptorNoLifeTimeCompare()))
            {
                throw new InvalidOperationException("You can only call this method once to register the GenericEventRunner and event handlers.");
            }
            services.AddSingleton <IGenericEventRunnerConfig>(config);
            services.AddTransient <IEventsRunner, EventsRunner>();
            debugLogs.Add($"Finished by registering the {nameof(EventsRunner)} and {nameof(GenericEventRunnerConfig)}");

            return(debugLogs);
        }
Beispiel #5
0
 /// <summary>
 /// This is the class that will manage the events inside your DbContext
 /// </summary>
 /// <param name="serviceProvider"></param>
 /// <param name="logger"></param>
 /// <param name="config"></param>
 public EventsRunner(IServiceProvider serviceProvider, ILogger <EventsRunner> logger, IGenericEventRunnerConfig config)
 {
     _config          = config ?? throw new ArgumentNullException(nameof(config));
     _eachEventRunner = new RunEachTypeOfEvents(serviceProvider, logger, _config);
 }
Beispiel #6
0
        /// <summary>
        /// This extension method provides a way to set up a DbContext with an EventsRunner and also registers all
        /// the event handlers in the assembly that the TRunner class is in.
        /// </summary>
        /// <typeparam name="TContext">Your DbContext type</typeparam>
        /// <typeparam name="THandler">The type of one of your event handlers.
        /// The whole assembly that the TRunner is in will be scanned for event handlers</typeparam>
        /// <param name="options">The <code>T:DbContextOptions{TContext}</code> for your DbContext</param>
        /// <param name="logs">Optional. If provided the it uses the EfCore.TestSupport logging provider to return logs</param>
        /// <param name="config">Optional. Allows you to change the configuration setting for GenericEventRunner</param>
        /// <returns>An instance of the DbContext created by DI and therefore containing the EventsRunner</returns>
        public static TContext CreateDbWithDiForHandlers <TContext, THandler>(this DbContextOptions <TContext> options,
                                                                              List <LogOutput> logs = null, IGenericEventRunnerConfig config = null) where TContext : DbContext where THandler : class
        {
            var services = new ServiceCollection();

            if (logs != null)
            {
                services.AddSingleton <ILogger <EventsRunner> >(new Logger <EventsRunner>(new LoggerFactory(new[]
                {
                    new MyLoggerProviderActionOut(logs.Add)
                })));
            }
            else
            {
                services.AddSingleton <ILogger <EventsRunner> >(new NullLogger <EventsRunner>());
            }

            var assembliesToScan = new Assembly[]
            {
                Assembly.GetAssembly(typeof(THandler)),
                Assembly.GetExecutingAssembly()         //This will pick up any event handlers in your unit tests assembly
            };

            services.RegisterGenericEventRunner(config ?? new GenericEventRunnerConfig(), assembliesToScan);
            services.AddSingleton(options);
            services.AddScoped <TContext>();
            var serviceProvider = services.BuildServiceProvider();
            var context         = serviceProvider.GetRequiredService <TContext>();

            return(context);
        }
Beispiel #7
0
        public static ExampleDbContext CreateAndSeedDbWithDiForHandlers <TRunner>(this DbContextOptions <ExampleDbContext> options,
                                                                                  List <LogOutput> logs = null, IGenericEventRunnerConfig config = null) where TRunner : class
        {
            var context = options.CreateDbWithDiForHandlers <ExampleDbContext, TRunner>(logs, config);

            context.Database.EnsureCreated();
            context.SeedTaxAndStock();

            return(context);
        }
 /// <summary>
 /// This is the class that will manage the events inside your DbContext
 /// </summary>
 /// <param name="serviceProvider"></param>
 /// <param name="logger"></param>
 /// <param name="config"></param>
 public EventsRunner(IServiceProvider serviceProvider, ILogger <EventsRunner> logger, IGenericEventRunnerConfig config)
 {
     _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
     _logger          = logger ?? throw new ArgumentNullException(nameof(logger));
     _config          = config ?? throw new ArgumentNullException(nameof(config));
 }