public static void AddApplicationServices(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddDataRepositories(configuration);
            services.AddAutoMapper(typeof(DependencyInjection).Assembly);

            // Add application services
            services.Scan(scan => scan
                          .FromAssembliesOf(typeof(ISubscriptionsService))
                          .AddClasses(classes => classes.InNamespaces(typeof(ISubscriptionsService).Namespace))
                          .AsImplementedInterfaces()
                          .WithScopedLifetime()
                          );

            #region Masstransit
            var rabbitmqOptions = new RabbitMqOptions();
            configuration.Bind(nameof(RabbitMqOptions), rabbitmqOptions);

            services.AddMassTransit(x =>
            {
                x.AddRequestClient <ActivateSubscription>(typeof(ActivateSubscription).GetQueueAddress());
                x.AddRequestClient <DeactivateSubscription>(typeof(DeactivateSubscription).GetQueueAddress());


                x.AddBus(busContext => Bus.Factory.CreateUsingRabbitMq(config =>
                {
                    config.Host(rabbitmqOptions.Uri, h =>
                    {
                        h.Username(rabbitmqOptions.Username);
                        h.Password(rabbitmqOptions.Password);
                    });

                    foreach (var @event in DomainEventsHelper.GetDomainEventTypes())
                    {
                        config.MessageTopology.SetEntityNameFormatter(new TypeFullNameEntityNameFormatter());
                    }

                    config.Publish <IDomainEvent>(c =>
                    {
                        c.Exclude = true;
                    });
                }));
            });

            #endregion
        }
        public SubscriptionMapping()
        {
            CreateMap <Subscription, SubscriptionModel>()
            .ForMember(dest => dest.Event, opt => opt.MapFrom(src => DomainEventsHelper.GetDomainEventTypes().SingleOrDefault(t => t.FullName == src.Event)))
            .ForMember(dest => dest.EventName, opt => opt.MapFrom(src => src.Event))
            .ForMember(dest => dest.Headers, opt => opt.MapFrom(src => src.Headers.ToDictionary(h => h.Key, h => h.Value)));

            CreateMap <SubscriptionAddModel, Subscription>()
            .ForMember(dest => dest.Endpoint, opt => opt.MapFrom(src => src.Endpoint))
            .ForMember(dest => dest.Headers, opt => opt.MapFrom(src => src.Headers.Select(h => new SubscriptionHeader()
            {
                SubscriptionId = src.Id,
                Key            = h.Key,
                Value          = h.Value
            })));

            CreateMap <SubscriptionModel, ActivateSubscription>();
            CreateMap <SubscriptionModel, DeactivateSubscription>();
        }
        public async Task <IActionResult> AddOrderLine(AddOrderLineRequest request)
        {
            var orderId = Guid.Parse("33d4201c-4a8e-40a2-ae1d-50bc64097085");

            var order = await _ordersContext.Orders.FindAsync(orderId);

            Thread.Sleep(3000);

            order.AddOrderLine(request.ProductCode);

            var domainEvents = DomainEventsHelper.GetAllDomainEvents(order);

            if (domainEvents.Any())
            {
                order.IncreaseVersion();
            }

            await _ordersContext.SaveChangesAsync();

            return(Ok());
        }
Пример #4
0
        public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
        .UseWindowsService()
        .ConfigureServices((hostContext, services) =>
        {
            var configuration = hostContext.Configuration;

            // Add logging
            Log.Logger = new LoggerConfiguration()
                         .ReadFrom.Configuration(configuration)
                         .CreateLogger();
            services.AddLogging(c => c.AddSerilog());

            // Add application options
            services.AddDataRepositories(configuration);

            // Add options
            services.Configure <DeliveryOptions>(configuration.GetSection(nameof(DeliveryOptions)));
            services.Configure <RabbitMqOptions>(configuration.GetSection(nameof(RabbitMqOptions)));

            RabbitMqOptions rabbitmqOptions = null;
            DeliveryOptions deliveryOptions = null;
            IEnumerable <Subscription> subscriptions;

            using (var provider = services.BuildServiceProvider())
            {
                rabbitmqOptions = provider.GetService <IOptions <RabbitMqOptions> >().Value;
                deliveryOptions = provider.GetService <IOptions <DeliveryOptions> >().Value;
                subscriptions   = provider.GetService <ISubscriptonsRepository>().GetSubscriptions(true).Result;
            }

            #region MassTransit config
            services.AddMassTransit(x =>
            {
                x.AddBus(busContext => Bus.Factory.CreateUsingRabbitMq(config =>
                {
                    config.Host(rabbitmqOptions.Uri, h =>
                    {
                        h.Username(rabbitmqOptions.Username);
                        h.Password(rabbitmqOptions.Password);
                    });

                    #region Command consumers

                    x.AddConsumer <ActivateSubscriptionConsumer>();
                    config.ReceiveEndpoint(queueName: typeof(ActivateSubscription).FullName, c =>
                    {
                        c.ConfigureConsumeTopology = false;
                        c.ConfigureConsumer <ActivateSubscriptionConsumer>(busContext);
                    });

                    x.AddConsumer <DeactivateSubscriptionConsumer>();
                    config.ReceiveEndpoint(queueName: typeof(DeactivateSubscription).FullName, c =>
                    {
                        c.ConfigureConsumeTopology = false;
                        c.ConfigureConsumer <DeactivateSubscriptionConsumer>(busContext);
                    });

                    #endregion

                    #region Event consumers
                    foreach (var subscription in subscriptions)
                    {
                        var eventType = DomainEventsHelper.GetDomainEventTypes().SingleOrDefault(t => t.FullName == subscription.Event);
                        if (eventType == null)
                        {
                            continue;         // TODO: Log invalid event
                        }
                        #region Add event consumers
                        var addConsumerMethod = x.GetType()
                                                .GetMethods().Single(m => m.Name == nameof(IServiceCollectionBusConfigurator.AddConsumer) &&
                                                                     m.ContainsGenericParameters &&
                                                                     m.GetParameters().Length == 1 &&
                                                                     m.GetParameters()[0].ParameterType.IsGenericType &&
                                                                     m.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(Action <>)
                                                                     )
                                                .MakeGenericMethod(typeof(DomainEventConsumer <>).MakeGenericType(eventType));
                        addConsumerMethod.Invoke(x, new object[] { null });

                        //x.AddConsumer(eventType);
                        //x.AddConsumer<DomainEventConsumer<OperationCompletedEvent>>();

                        #endregion

                        #region Configure event consumers
                        config.ReceiveEndpoint(queueName: $"{subscription.Event}_{subscription.Id}", c =>
                        {
                            c.Bind(exchangeName: eventType.FullName);
                            c.UseMessageRetry(r => r.Interval(deliveryOptions.Attempts, TimeSpan.FromSeconds(deliveryOptions.AttemptDelay)));
                            c.ConfigureConsumeTopology  = false;
                            var configureConsumerMethod = typeof(RegistrationContextExtensions)
                                                          .GetMethods().Single(m => m.Name == nameof(RegistrationContextExtensions.ConfigureConsumer) &&
                                                                               m.ContainsGenericParameters &&
                                                                               m.GetParameters().Length == 3 &&
                                                                               m.GetParameters()[0].ParameterType == typeof(IReceiveEndpointConfigurator) &&
                                                                               m.GetParameters()[1].ParameterType == typeof(IRegistration) &&
                                                                               m.GetParameters()[2].ParameterType.IsGenericType &&
                                                                               m.GetParameters()[2].ParameterType.GetGenericTypeDefinition() == typeof(Action <>)
                                                                               )
                                                          .MakeGenericMethod(typeof(DomainEventConsumer <>).MakeGenericType(eventType));

                            configureConsumerMethod.Invoke(null, new object[] { c, busContext, null });

                            //c.ConfigureConsumer(busContext, eventType);
                            //c.ConfigureConsumer<DomainEventConsumer<OperationCompletedEvent>>(busContext);
                        });
                        #endregion
                    }
                    #endregion
                }));
            });

            services.AddScoped <ActivateSubscriptionConsumer>();
            services.AddScoped <DeactivateSubscriptionConsumer>();

            foreach (var @event in DomainEventsHelper.GetDomainEventTypes())
            {
                services.AddScoped(typeof(DomainEventConsumer <>).MakeGenericType(@event));
            }

            #endregion

            #region HttpClientFactory config
            services.AddHttpClient(HttpClientNames.WebhookSubscriptionHttpClient, c =>
            {
                if (deliveryOptions.Timeout > 0)
                {
                    c.Timeout = TimeSpan.FromSeconds(deliveryOptions.Timeout);
                }
            });
            #endregion

            services.AddHostedService <Worker>();
        });
        /// <inheritdoc/>
        public async Task <Type> GetEventType(string name)
        {
            var @event = DomainEventsHelper.GetDomainEventTypes().SingleOrDefault(e => e.FullName.Equals(name, StringComparison.InvariantCultureIgnoreCase));

            return(await Task.FromResult(@event));
        }
 /// <inheritdoc/>
 public async Task <IEnumerable <Type> > GetEvents()
 {
     return(await Task.FromResult(DomainEventsHelper.GetDomainEventTypes()));
 }