예제 #1
0
        /// <summary>
        /// Perform the bootstrapping of all configured services.
        /// </summary>
        /// <returns>Collection of generated notifications.</returns>
        public IEnumerable <BootstrapperNotification> Bootstrapp()
        {
            var iocServiceExists = _services.Any(s => s.ServiceType == BootstrapperServiceType.IoC);

            if (_checkOptimal)
            {
                CheckIfOptimal();
            }
            if (_iocRegistrations.Count > 0 && !iocServiceExists)
            {
                if (_strict)
                {
                    throw new InvalidOperationException("Bootstsrapper.Bootstrapp() : Some IoC registrations " +
                                                        "has been made but no IoC has been registered. System cannot work.");
                }
                else
                {
                    _notifications.Add(new BootstrapperNotification
                    {
                        Type        = BootstrapperNotificationType.Error,
                        ContentType = BootstapperNotificationContentType.IoCRegistrationsHasBeenMadeButNoIoCService
                    });
                }
            }
            if (iocServiceExists)
            {
                AddDispatcherToIoC();
                AddToolboxToIoC();
            }
            var context = new BootstrappingContext(
                _services.Select(s => s.ServiceType).Distinct(),
                _iocRegistrations.SelectMany(r => r.AbstractionTypes)
                )
            {
                CheckOptimal = _checkOptimal,
                Strict       = _strict
            };

            foreach (var service in _services.OrderByDescending(s => s.ServiceType))
            {
                service.BootstrappAction.Invoke(context);
            }
            if (_throwExceptionOnErrorNotif && _notifications.Any(n => n.Type == BootstrapperNotificationType.Error))
            {
                throw new BootstrappingException(_notifications);
            }
            return(_notifications.AsEnumerable());
        }
예제 #2
0
        private void BootstrappServices(IEnumerable <IBootstrapperService> services)
        {
            var iocServiceExists = services.Any(s => s.ServiceType == BootstrapperServiceType.IoC);

            if (checkOptimal)
            {
                CheckIfOptimal();
            }
            if (iocRegistrations.Count > 0 && !iocServiceExists)
            {
                if (strict)
                {
                    throw new InvalidOperationException("Bootstsrapper.Bootstrapp() : Some IoC registrations " +
                                                        "has been made but no IoC has been registered. System cannot work.");
                }
                else
                {
                    notifications.Add(new BootstrapperNotification
                    {
                        Type        = BootstrapperNotificationType.Error,
                        ContentType = BootstapperNotificationContentType.IoCRegistrationsHasBeenMadeButNoIoCService
                    });
                }
            }
            if (iocServiceExists)
            {
                AddDispatcherToIoC();
                AddToolboxToIoC();
                AddRepositoriesToIoC();
            }
            var context = new BootstrappingContext(
                services.Select(s => s.ServiceType).Distinct(),
                iocRegistrations.SelectMany(r => r.AbstractionTypes),
                this
                )
            {
                CheckOptimal = checkOptimal,
                Strict       = strict
            };

            foreach (var service in services.OrderByDescending(s => s.ServiceType))
            {
                service.BootstrappAction.Invoke(context);
            }
        }
예제 #3
0
        private static IEnumerable <BootstrapperNotification> PerformEventChecksAccordingToBootstrapperParameters(BootstrappingContext ctx,
                                                                                                                  InMemoryEventBusConfiguration configuration)
        {
            var notifs = new List <BootstrapperNotification>();

            foreach (var evtType in _allTypes.Where(t => typeof(IDomainEvent).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract).AsParallel())
            {
                var handlers = _allTypes.Where(t => typeof(IDomainEventHandler <>).MakeGenericType(evtType).IsAssignableFrom(t)).ToList();
                if (handlers.Count == 0)
                {
                    if (ctx.CheckOptimal)
                    {
                        notifs.Add(
                            new BootstrapperNotification(
                                BootstrapperNotificationType.Warning,
                                $"Your project doesn't contain any handler for event type {evtType.FullName}, which is generally not desired (you forget to add implementation of it). When implementing it, don't forget to allow InMemoryEventBus to be able to retrieve it (by adding it to your IoC container or by creating a parameterless constructor to allow to create it by reflection). If this is desired, you can ignore this warning.",
                                typeof(InMemoryEventBus))
                            );
                    }
                }
                var isHandlerCritical = handlers.Any(h => h.IsDefined(typeof(CriticalHandlerAttribute)));
                if (isHandlerCritical && configuration?.ParallelHandling.Any(e => e == evtType) == true)
                {
                    notifs.Add(
                        new BootstrapperNotification(
                            BootstrapperNotificationType.Warning,
                            $"There are multiples handlers for event type {evtType.FullName}, and at least one of them is marked as 'critical', meaning next ones shouldn't be called if critical failed. However, your configuration for this specific event type says they're allowed to run in parallel. This configuration *cannot* ensure that critical handlers will block next ones, you should review your configuration (by setting ShouldWait to true) or remove CriticalHandler attribute, which can't be ensured in this case.",
                            typeof(InMemoryEventBus))
                        );
                }
            }
            return(notifs.AsEnumerable());
        }
예제 #4
0
        private static IEnumerable <BootstrapperNotification> PerformCommandChecksAccordingToBootstrapperParameters(BootstrappingContext ctx,
                                                                                                                    InMemoryCommandBusConfiguration configuration)
        {
            var notifs = new List <BootstrapperNotification>();

            foreach (var cmdType in _allTypes.Where(t => typeof(ICommand).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract).AsParallel())
            {
                var handlers = _allTypes.Where(t => typeof(ICommandHandler <>).MakeGenericType(cmdType).IsAssignableFrom(t)).ToList();
                if (handlers.Count == 0)
                {
                    if (ctx.CheckOptimal)
                    {
                        notifs.Add(
                            new BootstrapperNotification(
                                BootstrapperNotificationType.Warning,
                                $"Your project doesn't contain any handler for command type {cmdType.FullName}, which is generally not desired (you forget to add implementation of it). When implementing it, don't forget to allow InMemoryCommandBus to be able to retrieve it (by adding it to your IoC container or by creating a parameterless constructor to allow to create it by reflection). If this is desired, you can ignore this warning.",
                                typeof(InMemoryCommandBus))
                            );
                    }
                }
                else if (handlers.Count > 1)
                {
                    if (ctx.Strict)
                    {
                        if (ctx.CheckOptimal)
                        {
                            notifs.Add(
                                new BootstrapperNotification(
                                    BootstrapperNotificationType.Error,
                                    $"Your project contains more than one handler for command type {cmdType.FullName}. This is not allowed by best practices, even if you configured it in the configuration, because you've configured your bootstrapper to be 'strict' and 'optimal'. To get rid of this error, remove handlers until you get only one left, or change your bootstrapper configuration.",
                                    typeof(InMemoryCommandBus))
                                );
                        }
                        else
                        {
                            notifs.Add(
                                new BootstrapperNotification(
                                    BootstrapperNotificationType.Warning,
                                    $"Your project contains more than one handler for command type {cmdType.FullName}. This is generally a bad practice, even if you configured it in the configuration. It is recommended to have only one handler per command type to avoid multiple treatment of same command. This warning can be remove by passing false to bootstrapper for the 'strict' flag.",
                                    typeof(InMemoryCommandBus))
                                );
                        }
                    }
                }
                var isHandlerCritical = handlers.Any(h => h.IsDefined(typeof(CriticalHandlerAttribute)));
                if (isHandlerCritical && configuration?.CommandAllowMultipleHandlers.Any(t => t.CommandType == cmdType && !t.ShouldWait) == true)
                {
                    notifs.Add(
                        new BootstrapperNotification(
                            BootstrapperNotificationType.Warning,
                            $"There are multiples handlers for command type {cmdType.FullName}, and at least one of them is marked as 'critical', meaning next ones shouldn't be called if critical failed. However, your configuration for multiple handlers for this specific command type doesn't state that handlers should wait for completion, meaning they're running in parallel. This configuration *cannot* ensure that critical handlers will block next ones, you should review your configuration (by setting ShouldWait to true) or remove CriticalHandler attribute, which can't be ensured in this case.",
                            typeof(InMemoryCommandBus))
                        );
                }
            }

            return(notifs.AsEnumerable());
        }
예제 #5
0
 internal static void ConfigureInMemoryEventBus(Bootstrapper bootstrapper, InMemoryEventBusConfiguration?configuration, string[] excludedEventsDLLs, BootstrappingContext ctx)
 {
     InMemoryEventBus.InitHandlersCollection(excludedEventsDLLs);
     if (ctx.IsServiceRegistered(BootstrapperServiceType.IoC))
     {
         bootstrapper.AddIoCRegistration(new TypeRegistration(typeof(InMemoryEventBus), typeof(IDomainEventBus), typeof(InMemoryEventBus)));
         if (configuration != null)
         {
             bootstrapper.AddIoCRegistration(new InstanceTypeRegistration(configuration, typeof(InMemoryEventBusConfiguration)));
         }
     }
     bootstrapper.AddNotifications(PerformEventChecksAccordingToBootstrapperParameters(ctx, configuration));
 }