public async Task AddProductToCart() { var rmqUri = new Uri("amqp://*****:*****@localhost:5672/vhost"); var services = new ServiceCollection(); services.AddTransient <IProductRepository, FakeProductRepository>(); using var resolver = EventFlowOptions.New .UseServiceCollection(services) .AddDefaults(typeof(CartContext).Assembly) .UseEntityFrameworkEventStore <CartContext>() .ConfigureEntityFramework(EntityFrameworkConfiguration.New) .AddDbContextProvider <CartContext, MySqlCartContextProvider>() .AddEvents(typeof(ProductAddedEvent)) .AddCommands(typeof(AddProductCommand)) .AddCommandHandlers(typeof(AddProductCommandHandler)) .PublishToRabbitMq(RabbitMqConfiguration.With(rmqUri)) .CreateResolver(); var commandBus = resolver.Resolve <ICommandBus>(); var aggregateStore = resolver.Resolve <IAggregateStore>(); CartId cartId = CartId.NewCartId(); await commandBus.PublishAsync( new AddProductCommand(cartId, new ProductId(Guid.Empty)), CancellationToken.None); Cart cart = await aggregateStore.LoadAsync <Cart, CartId>(cartId, CancellationToken.None); Assert.AreEqual(1, cart.Products.Count); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddControllers(); ConfigureSwagger(services); services.AddAutoMapper(typeof(Startup)); services.AddEventFlow(ef => { var envconfig = EnvironmentConfiguration.Bind(Configuration); services.AddSingleton(envconfig); ef.AddDefaults(typeof(Startup).Assembly); //ef.Configure(cfg => cfg.IsAsynchronousSubscribersEnabled = true); ef.PublishToRabbitMq( RabbitMqConfiguration.With(new Uri(envconfig.RabbitMqConnection), true, 5, envconfig.RabbitExchange)); ef.AddAspNetCore(); //ef.UseHangfireJobScheduler(); ef.UseConsoleLog(); ef.RegisterModule <DomainModule>(); ef.RegisterModule <AccountingReadModelModule>(); ef.RegisterServices(s => { s.Register <ICustomerCommandService, CustomerCommandService>(); s.Register <IAccountCommandService, AccountCommandService>(); s.Register <ITransactionCommandService, TransactionCommandService>(); }); }); }
// This method gets called by the runtime. Use this method to add services to the container. public IServiceProvider ConfigureServices(IServiceCollection services) { var eventStoreUri = new Uri("tcp://localhost:1113", UriKind.Absolute); var rabbmitMqUri = new Uri("amqp://localhost", UriKind.Absolute); var mongoUrl = "mongodb://localhost:27017"; services.AddMvc(); var builder = new ContainerBuilder(); var container = EventFlowOptions.New .UseAutofacContainerBuilder(builder) .ConfigureMongoDb(mongoUrl, "pages") .PublishToRabbitMq(RabbitMqConfiguration.With(rabbmitMqUri)) //.ConfigureElasticsearch(new Uri("http://localhost:9200")) //.UseElasticsearchReadModel<StoryReadModel>() .UseEventStoreEventStore(eventStoreUri) .UseInMemorySnapshotStore() .AddDefaults(Assembly) .UseMongoDbReadModel <UserReadModel>() .AddMetadataProvider <AddGuidMetadataProvider>() .AddAspNetCoreMetadataProviders(); builder.Populate(services); ApplicationContainer = builder.Build(); return(new AutofacServiceProvider(ApplicationContainer)); }
public static async Task Main(string[] args) { var builder = new HostBuilder() .ConfigureAppConfiguration((host, config) => { config.SetBasePath(Directory.GetCurrentDirectory()); config.AddJsonFile("appsettings.json", true, true); config.AddJsonFile($"appsettings.{host.HostingEnvironment.EnvironmentName}.json", true, true); config.AddEnvironmentVariables(); }) .ConfigureServices( (hostcontext, services) => { var envconfig = EnvironmentConfiguration.Bind(hostcontext.Configuration); services.AddSingleton(envconfig); EventFlowOptions.New .Configure(cfg => cfg.IsAsynchronousSubscribersEnabled = true) .UseServiceCollection(services) .AddAspNetCoreMetadataProviders() .PublishToRabbitMq(RabbitMqConfiguration.With(new Uri($"{envconfig.RabbitMqConnection}"), true, 5, envconfig.RabbitExchange)) .RegisterModule <DomainModule>() // // subscribe services changed // .AddAsynchronousSubscriber <VehicleAggregate, VehicleId, LocationUpdatedEvent, RabbitMqConsumePersistanceService>() .RegisterServices(s => { s.Register <IHostedService, RabbitConsumePersistenceService>(Lifetime.Singleton); s.Register <IHostedService, RabbitMqConsumePersistanceService>(Lifetime.Singleton); }); }) .ConfigureLogging((hostingContext, logging) => { }); await builder.RunConsoleAsync(); }
public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSwaggerGen(x => { x.SwaggerDoc("v1", new OpenApiInfo { Title = "Read Api Eventflow Demo - API", Version = "v1" }); }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0); string elasticSearchUrl = Environment.GetEnvironmentVariable("ELASTICSEARCHURL"); ContainerBuilder containerBuilder = new ContainerBuilder(); Uri node = new Uri(elasticSearchUrl); ConnectionSettings settings = new ConnectionSettings(node); settings.DisableDirectStreaming(); ElasticClient elasticClient = new ElasticClient(settings); string rabbitMqConnection = Environment.GetEnvironmentVariable("RABBITMQCONNECTION"); Options = EventFlowOptions.New .UseAutofacContainerBuilder(containerBuilder) .AddDefaults(typeof(Employee).Assembly) .ConfigureElasticsearch(() => elasticClient) .RegisterServices(sr => sr.Register <IScopedContext, ScopedContext>(Lifetime.Scoped)) .RegisterServices(sr => sr.RegisterType(typeof(EmployeeLocator))) .UseElasticsearchReadModel <EmployeeReadModel, EmployeeLocator>() .RegisterServices(sr => sr.RegisterType(typeof(TransactionLocator))) .UseElasticsearchReadModel <TransactionReadModel, TransactionLocator>() .AddQueryHandlers(typeof(ESTransactionGetQueryHandler), typeof(ESEmployeeGetQueryHandler)) .AddAsynchronousSubscriber <EmployeeAggregate, EmployeeId, EmployeeAddedEvent, AddNewEmployeeSubscriber>() .AddSubscribers(typeof(AllEventsSubscriber)) .Configure(c => c.IsAsynchronousSubscribersEnabled = true) .Configure(c => c.ThrowSubscriberExceptions = true) .SubscribeToRabbitMq( RabbitMqConfiguration.With(new Uri(rabbitMqConnection), true, 5, "eventflow")) .AddAspNetCore(); containerBuilder.Populate(services); var container = containerBuilder.Build(); using (var scope = container.BeginLifetimeScope()) { var subscriber = scope.Resolve <IRabbitMqSubscriber>(); var configuration = scope.Resolve <IRabbitMqConfiguration>(); var domainEventPublisher = scope.Resolve <IDomainEventPublisher>(); subscriber.SubscribeAsync(configuration.Exchange, configuration.Exchange + "Queue", EventFlowOptionsRabbitMqExtensions.Listen, domainEventPublisher, cancellationToken: CancellationToken.None).Wait(); } var _tenantIndex = new ElasticSearchIndex(elasticSearchUrl); _tenantIndex.CreateIndex("employeeindex", elasticSearchUrl); services.AddSingleton(_tenantIndex.ElasticClient); return(new AutofacServiceProvider(container)); }
private IRootResolver BuildResolver(Exchange exchange, Func <IEventFlowOptions, IEventFlowOptions> configure = null) { configure = configure ?? (e => e); return(configure(EventFlowOptions.New .PublishToRabbitMq(RabbitMqConfiguration.With(_uri, false, exchange: exchange.Value)) .AddDefaults(EventFlowTestHelpers.Assembly)) .CreateResolver(false)); }
private IRootResolver BuildResolver(Exchange exchange, Func <IEventFlowOptions, IEventFlowOptions> configure = null) { configure = configure ?? (e => e); return(configure(EventFlowOptions.New .PublishToRabbitMq(RabbitMqConfiguration.With(_uri, false, exchange: exchange.Value)) .AddDefaults(EventFlowTestHelpers.Assembly)) .RegisterServices(sr => sr.Register <IScopedContext, ScopedContext>(Lifetime.Scoped)) .CreateResolver(false)); }
public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSwaggerGen(x => { x.SwaggerDoc("v1", new OpenApiInfo { Title = "Eventflow Demo - API", Version = "v1" }); x.OperationFilter <SwaggerAuthorizationHeaderParameterOperationFilter>(); }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0); ContainerBuilder containerBuilder = new ContainerBuilder(); string rabbitMqConnection = Environment.GetEnvironmentVariable("RABBITMQCONNECTION"); string elasticSearchUrl = Environment.GetEnvironmentVariable("ELASTICSEARCHURL"); Uri node = new Uri(elasticSearchUrl); ConnectionSettings settings = new ConnectionSettings(node); var dataRetrieval = new DataRetrieval() { Enabled = true }; settings.DisableDirectStreaming(); ElasticClient elasticClient = new ElasticClient(settings); EventFlowOptions.New .UseAutofacContainerBuilder(containerBuilder) .AddDefaults(typeof(Employee).Assembly) .ConfigureEventStore() .ConfigureElasticsearch(() => elasticClient) .PublishToRabbitMq( RabbitMqConfiguration.With(new Uri(rabbitMqConnection), true, 5, "eventflow")) .RegisterServices(sr => sr.Register <IScopedContext, ScopedContext>(Lifetime.Scoped)) .RegisterServices(sr => sr.RegisterType(typeof(EmployeeLocator))) .UseElasticsearchReadModel <EmployeeReadModel, EmployeeLocator>() .RegisterServices(sr => sr.RegisterType(typeof(TransactionLocator))) .UseElasticsearchReadModel <TransactionReadModel, TransactionLocator>() .ConfigureDataRetrieval(dataRetrieval, typeof(EmployeeReadModel).Assembly) .AddAspNetCore(); containerBuilder.Populate(services); var _tenantIndex = new ElasticSearchIndex(elasticSearchUrl); _tenantIndex.CreateIndex("employeeindex", elasticSearchUrl); services.AddSingleton(_tenantIndex.ElasticClient); return(new AutofacServiceProvider(containerBuilder.Build())); }
public void Register(IEventFlowOptions options) { options .AddDefaults(typeof(TransactionReadModelModule).Assembly) .Configure(cfg => cfg.IsAsynchronousSubscribersEnabled = true) .SubscribeToRabbitMq(RabbitMqConfiguration.With(new Uri(@"amqp://*****:*****@localhost:5672"))) .UseInMemoryReadStoreFor <TransactionServiceReadModel>() //.AddSubscribers(typeof(AllEventsSubscriber)) //.AddAsynchronousSubscriber<AccountAggregate, AccountId,AccountRegisterCompletedEvent, AccountRegisterCompletedSubscriber>() .RegisterServices(s => { s.Register <ITransactionQueryService, TransactionQueryService>(); s.Register <IReadModelStore <TransactionServiceReadModel>, InMemoryReadStore <TransactionServiceReadModel> >(); s.Register <ISubscribeSynchronousToAll, RabbitMqDomainEventSubscriber>(); }); }
public async Task PassingTest() { using (var resolver = EventFlowOptions.New .UseAutofacContainerBuilder(new ContainerBuilder()) .Configure(c => c.ThrowSubscriberExceptions = true) .AddEvents(typeof(ExampleEvent)) .AddEvents(typeof(ResetEvent)) .AddCommands(typeof(ExampleCommand)) .AddCommands(typeof(ResetCommand)) .AddCommandHandlers(typeof(ExampleCommandHandler)) .AddCommandHandlers(typeof(ResetCommandHandler)) .ConfigureEventStore() .ConfigureMongoDb(MongoClient, SNAPSHOT_CONTAINER_NAME) .AddSnapshots(typeof(ExampleSnaphost)) .UseMongoDbSnapshotStore() .UseInMemoryReadStoreFor <ExampleReadModel>() .RegisterServices(sr => sr.Register(i => SnapshotEveryFewVersionsStrategy.Default)) .RegisterServices(DecorateCommandBus) .PublishToRabbitMq(RabbitMqConfiguration.With(RabbitMqUri, true, 4, "eventflow")) .Configure(c => c.IsAsynchronousSubscribersEnabled = true) .AddJobs(typeof(ExampleJob)) .CreateResolver()) { Int32 magicNumber = 2; CommandBus = resolver.Resolve <ICommandBus>(); ExampleId exampleId = PublishCommand.GetStreamName("Tenant", "EXAMPLE"); CommandReturnResult result = await CommandBus.PublishAsync( new ExampleCommand(exampleId, magicNumber), CancellationToken.None) .ConfigureAwait(false); IAggregateStore aggregateStore = resolver.Resolve <IAggregateStore>(); var @aggregate = await aggregateStore.LoadAsync <ExampleAggregate, ExampleId>(exampleId, CancellationToken.None); //Command side result.IsSuccess.Should().BeTrue(); result.AggregateRoot.Should().NotBeNull(); result.AggregateRoot.Version.Should().Be(1); result.AggregateRoot.Name.Value.Should().Be("ExampleAggregate"); result.AggregateRoot.GetIdentity().Value.Should().Be(exampleId.Value); @aggregate.Should().NotBeNull(); result.AggregateRoot.Should().Equals(@aggregate); } }
public Bootstrap() { var mquri = new Uri("amqp://*****:*****@127.0.0.1"); var mqconf = RabbitMqConfiguration.With( mquri, true, 5, "loxnet" ); _resolver = EventFlowOptions.New .ConfigureTransportDomain() .UseConsoleLog() .PublishToRabbitMq(mqconf) .CreateResolver(); _aggregateStore = _resolver .Resolve <IAggregateStore>(); _commandBus = _resolver .Resolve <ICommandBus>(); }
public async Task ReadModelTest() { using (var resolver = EventFlowOptions.New .UseAutofacContainerBuilder(new ContainerBuilder()) .Configure(c => c.ThrowSubscriberExceptions = true) .AddEvents(typeof(ExampleEvent)) .AddEvents(typeof(ResetEvent)) .AddCommands(typeof(ExampleCommand)) .AddCommands(typeof(ResetCommand)) .AddCommandHandlers(typeof(ExampleCommandHandler)) .AddCommandHandlers(typeof(ResetCommandHandler)) .ConfigureEventStore() .ConfigureMongoDb(MongoClient, SNAPSHOT_CONTAINER_NAME) .AddSnapshots(typeof(ExampleSnaphost)) .UseMongoDbSnapshotStore() .UseInMemoryReadStoreFor <ExampleReadModel>() .RegisterServices(sr => sr.Register(i => SnapshotEveryFewVersionsStrategy.Default)) .RegisterServices(DecorateCommandBus) .PublishToRabbitMq(RabbitMqConfiguration.With(RabbitMqUri, true, 4, "eventflow")) .Configure(c => c.IsAsynchronousSubscribersEnabled = true) .AddJobs(typeof(ExampleJob)) .CreateResolver()) { Int32 magicNumber = 2; CommandBus = resolver.Resolve <ICommandBus>(); ExampleId exampleId = PublishCommand.GetStreamName("Tenant", "EXAMPLE"); CommandReturnResult result = await CommandBus.PublishAsync( new ExampleCommand(exampleId, magicNumber), CancellationToken.None) .ConfigureAwait(false); var queryProcessor = resolver.Resolve <IQueryProcessor>(); ExampleReadModel exampleReadModel = await queryProcessor.ProcessAsync( new ReadModelByIdQuery <ExampleReadModel>(exampleId), CancellationToken.None) .ConfigureAwait(false); exampleReadModel.Should().NotBeNull(); exampleReadModel.MagicNumber.Should().ContainSingle(); exampleReadModel.MagicNumber.First().Should().Be(2); } }
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { var env = EnvironmentConfiguration.Bind(_configuration); services.ConfigureServices(env, typeof(Startup), new OpenApiInfo { Title = "Movies API", Version = "v1" }); EventFlowOptions.New .UseServiceCollection(services) .AddDefaults(typeof(Startup).Assembly) .AddAspNetCore() .UseConsoleLog() .RegisterModule <DomainModule>() .RegisterModule <MovieReadStoreModule>() .RegisterModule <EventSourcingModule>() .PublishToRabbitMq(RabbitMqConfiguration.With(new Uri(env.RabbitMqConnection))) .CreateServiceProvider(); }
// This method gets called by the runtime. Use this method to add services to the container. public IServiceProvider ConfigureServices(IServiceCollection services) { var env = EnvironmentConfiguration.Bind(_configuration); services.AddAutoMapper() .AddSingleton(env) .AddSwaggerGen(c => c.SwaggerDoc("v1", new Info { Title = "Vehicles API", Version = "v1" })) .AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); return(EventFlowOptions.New .UseServiceCollection(services) .AddAspNetCoreMetadataProviders() .UseConsoleLog() .RegisterModule <DomainModule>() .RegisterModule <VehicleReadStoreModule>() .RegisterModule <EventSourcingModule>() .PublishToRabbitMq(RabbitMqConfiguration.With(new Uri(env.RabbitMqConnection))) .CreateServiceProvider()); }
public static void AddEventSourcing(this ContainerBuilder containerBuilder, IConfiguration configuration) { var snapshotStoreSettings = configuration.GetSnapshotStoreSettings(); var rabbitMQSettings = configuration.GetRabbitMQSettings(); var eventStoreSettings = configuration.GetEventStoreSettings(); var rabbitMQConfiguration = RabbitMqConfiguration.With(new Uri($"amqp://{rabbitMQSettings.UserName}:{rabbitMQSettings.Password}@{rabbitMQSettings.Host}:{rabbitMQSettings.Port}"), rabbitMQSettings.Persistent.Value, 5, rabbitMQSettings.ExchangeName); EventFlowOptions.New .UseAutofacContainerBuilder(containerBuilder) // Must be the first line! .Configure(c => c.ThrowSubscriberExceptions = true) .RegisterModule <UserModule>() .AddAspNetCore(options => { options.AddUserClaimsMetadata(); options.AddDefaultMetadataProviders(); }) .ConfigureEventStore(eventStoreSettings) .ConfigureMongoDb(new MongoClient(snapshotStoreSettings.ConnectionString), snapshotStoreSettings.Name) .UseMongoDbSnapshotStore() .RegisterServices(sr => sr.Register(i => SnapshotEveryFewVersionsStrategy.Default)) .PublishToRabbitMq(rabbitMQConfiguration); }
public async Task PublishCommandAsync() { var client = new MongoClient("mongodb://*****:*****@"amqp://test:test@localhost:5672"), true, 4, "eventflow")) //.ConfigureSagas() //.UseNullLog() //.UseInMemoryReadStoreFor<Aggregates.ReadModels.ExampleReadModel>() .Configure(c => c.IsAsynchronousSubscribersEnabled = true) //.AddAsynchronousSubscriber<ExampleAggregate, Aggregates.Events.ExampleId, ExampleEvent, RabbitMqConsumePersistanceService>() //.RegisterServices(s => { // s.Register<IHostedService, RabbitConsumePersistenceService>(Lifetime.Singleton); // s.Register<IHostedService, RabbitMqConsumePersistanceService>(Lifetime.Singleton); //}) //.AddSubscribers(new Type[] { typeof(ExampleSyncSubscriber) }) // .UseHangfireJobScheduler() .AddJobs(typeof(ExampleJob)) .CreateResolver()) { Int32 magicNumber = 2; CommandBus = resolver.Resolve <ICommandBus>(); var clock = new Stopwatch(); clock.Start(); ExampleId exampleId = GetStreamName("Tenant", "EXAMPLE"); for (int i = 0; i < 1; i++) { IExecutionResult result = await CommandBus.PublishAsync(new ExampleCommand(exampleId, magicNumber), CancellationToken.None) .ConfigureAwait(false); #region Comments //result.IsSuccess.Should().BeTrue(); //IAggregateStore aggregateStore = resolver.Resolve<IAggregateStore>(); //var @object = aggregateStore.LoadAsync<ExampleAggregate, ExampleId>(exampleId, CancellationToken.None); ////Obsolete ////IEventStore eventStore = resolver.Resolve<IEventStore>(); ////var aggregate = await eventStore.LoadAggregateAsync<ExampleAggregate, ExampleId>(exampleId, CancellationToken.None); ////state of our aggregate root //var queryProcessor = resolver.Resolve<IQueryProcessor>(); //var result = await queryProcessor.ProcessAsync( // new ReadModelByIdQuery<ExampleReadModel>(exampleId), // CancellationToken.None) // .ConfigureAwait(false); //// Verify that the read model has the expected magic number //exampleReadModel.MagicNumber.Should().Be(42); #endregion } clock.Stop(); Console.WriteLine("Duration: " + clock.ElapsedMilliseconds + "ms"); } Console.ReadLine(); }