private void RegisterTenantServices() { foreach (var tenant in _manager.Tenants) { ITenant tenant1 = tenant; var esComponentName = tenant.Id + "-es"; var readModelDb = tenant1.Get <IMongoDatabase>("readmodel.db"); var mongoPersistenceOptions = new MongoPersistenceOptions(); mongoPersistenceOptions.DisableSnapshotSupport = true; mongoPersistenceOptions.ConcurrencyStrategy = ConcurrencyExceptionStrategy.FillHole; var nesUrl = new MongoUrl(tenant1.GetConnectionString("events")); var nesDb = new MongoClient(nesUrl).GetDatabase(nesUrl.DatabaseName); var eventsCollection = nesDb.GetCollection <BsonDocument>("Commits"); mongoPersistenceOptions.CheckpointGenerator = new InMemoryCheckpointGenerator(eventsCollection); tenant1.Container.Register( Classes .FromAssemblyContaining <DocumentDescriptor>() .BasedOn <IPipelineHook>() .WithServiceAllInterfaces(), Component .For <IStoreEvents>() .Named(esComponentName) .UsingFactory <EventStoreFactory, IStoreEvents>(f => { var hooks = tenant1.Container.ResolveAll <IPipelineHook>(); return(f.BuildEventStore( tenant1.GetConnectionString("events"), hooks, mongoPersistenceOptions: mongoPersistenceOptions )); }) .LifestyleSingleton(), Component .For <IRepositoryEx, RepositoryEx>() .ImplementedBy <RepositoryEx>() .Named(tenant.Id + ".repository") .DependsOn(Dependency.OnComponent(typeof(IStoreEvents), esComponentName)) .LifestyleTransient(), Component .For <ISnapshotManager>() .DependsOn(Dependency.OnValue("cacheEnabled", _config.EnableSnapshotCache)) .ImplementedBy <CachedSnapshotManager>(), Component .For <IAggregateCachedRepositoryFactory>() .ImplementedBy <AggregateCachedRepositoryFactory>() .DependsOn(Dependency.OnValue("cacheDisabled", false)), Component .For <ISnapshotPersistenceStrategy>() .ImplementedBy <NumberOfCommitsShapshotPersistenceStrategy>() .DependsOn(Dependency.OnValue("commitsThreshold", 100)), Component.For <ISnapshotPersister>() .ImplementedBy <MongoSnapshotPersisterProvider>() .DependsOn(Dependency.OnValue <IMongoDatabase>(readModelDb)) ); } }
public void Install(IWindsorContainer container, IConfigurationStore store) { // add rm prefix to collections CollectionNames.Customize = n => "rm." + n; var config = new ProjectionEngineConfig { EventStoreConnectionString = _tenant.GetConnectionString("events"), Slots = _config.EngineSlots, PollingMsInterval = _config.PollingMsInterval, ForcedGcSecondsInterval = _config.ForcedGcSecondsInterval, TenantId = _tenant.Id, DelayedStartInMilliseconds = _config.DelayedStartInMilliseconds, EngineVersion = _config.EngineVersion, BucketInfo = _config.BucketInfo, }; var readModelDb = _tenant.Get <IMongoDatabase>("readmodel.db"); container.Register( Component .For <IDocumentWriter>() .ImplementedBy <DocumentWriter>() .DependsOn(Dependency.OnValue <IMongoDatabase>(readModelDb)), Component .For(typeof(IReader <,>), typeof(IMongoDbReader <,>)) .ImplementedBy(typeof(MongoReaderForProjections <,>)) .DependsOn(Dependency.OnValue <IMongoDatabase>(readModelDb)) ); container.Register( Component .For <IHousekeeper>() .ImplementedBy <NullHouseKeeper>(), Component .For <INotifyToSubscribers>() .ImplementedBy <TNotifier>(), Component .For <ICommitEnhancer>() .ImplementedBy <CommitEnhancer>(), Component .For <INotifyCommitHandled>() .ImplementedBy <NullNotifyCommitHandled>(), Classes .FromAssemblyContaining <DocumentProjection>() .BasedOn <IProjection>() .Configure(r => r .DependsOn(Dependency.OnValue <TenantId>(_tenant.Id)) ) .WithServiceAllInterfaces() .LifestyleSingleton(), Component .For <IInitializeReadModelDb>() .ImplementedBy <InitializeReadModelDb>(), Component .For <IConcurrentCheckpointTracker>() .ImplementedBy <ConcurrentCheckpointTracker>() .DependsOn(Dependency.OnValue <IMongoDatabase>(readModelDb)), Component .For(new[] { typeof(ICollectionWrapper <,>), typeof(IReadOnlyCollectionWrapper <,>) }) .ImplementedBy(typeof(CollectionWrapper <,>)) .DependsOn(Dependency.OnValue <IMongoDatabase>(readModelDb)), Component .For <IRebuildContext>() .ImplementedBy <RebuildContext>() .DependsOn(Dependency.OnValue <bool>(RebuildSettings.NitroMode)), Component .For <IMongoStorageFactory>() .ImplementedBy <MongoStorageFactory>() .DependsOn(Dependency.OnValue <IMongoDatabase>(readModelDb)), Component .For <DocumentDescriptorByHashReader>(), Component .For <DeduplicationHelper>(), Component .For <IRecycleBin>() .ImplementedBy <RecycleBin>() .DependsOn(Dependency.OnValue <IMongoDatabase>(readModelDb)) ); if (!_config.IsReadmodelBuilder) { return; } //This registration made the entire ConcurrentProjectionEngine starts //so it is better to register after all the other components are registered //correctly. if (config.EngineVersion == "v1") { throw new NotSupportedException("V1 projection engine not supported anymore"); } else if (config.EngineVersion == "v2") { throw new NotSupportedException("V2 projection engine not supported anymore because of NES6 dropping standard commit polling client"); } else if (config.EngineVersion == "v3") { container.Register( Component.For <ProjectionEngineConfig>() .Instance(config), Component .For <ICommitPollingClient>() .ImplementedBy <CommitPollingClient2>() .DependsOn(Dependency.OnValue("id", "Main-Poller")) .LifeStyle.Transient, Component .For <ICommitPollingClientFactory>() .AsFactory(), Component .For <IRepositoryExFactory>() .AsFactory(), Component .For <Func <IPersistStreams, ICommitPollingClient> >() .Instance(ps => container.Resolve <ICommitPollingClient>( Arguments.FromProperties(new { persistStreams = ps }))), Component .For <ProjectionEngine, ITriggerProjectionsUpdate>() .ImplementedBy <ProjectionEngine>() .LifestyleSingleton() .StartUsingMethod(x => x.Start) .StopUsingMethod(x => x.Stop) ); } }