public async Task Setup(string endpoint, Version version) { _endpoint = endpoint; // Changes which affect minor version require a new projection, ignore revision and build numbers _version = new Version(version.Major, version.Minor); await _consumer.EnableProjection("$by_category").ConfigureAwait(false); _cancelation = new CancellationTokenSource(); var discoveredEvents = _messaging.GetMessageTypes().Where(x => typeof(IEvent).IsAssignableFrom(x)).OrderBy(x => x.FullName).ToList(); if (!discoveredEvents.Any()) { Logger.Warn($"Event consuming is enabled but we did not detect any IEvent handlers"); return; } // Dont use - we dont need category projection projecting our projection var stream = $"{_endpoint}.{_version}".Replace("-", ""); // Link all events we are subscribing to to a stream var functions = discoveredEvents .Select( eventType => $"'{eventType.AssemblyQualifiedName}': processEvent") .Aggregate((cur, next) => $"{cur},\n{next}"); // endpoint will get all events regardless of version of info // it will be up to them to handle upgrades if (_allEvents) { functions = "$any: processEvent"; } // Don't tab this '@' will create tabs in projection definition var definition = @" function processEvent(s,e) {{ linkTo('{1}', e); }} options({{ reorderEvents: true, processingLag: 500 }}) fromStreams([{0}]). when({{ {2} }});"; // Todo: replace with `fromCategories([])` when available var appDefinition = string.Format(definition, $"'$ce-{StreamTypes.Domain}','$ce-{StreamTypes.OOB}'", stream, functions); await _consumer.CreateProjection($"{stream}.app.projection", appDefinition).ConfigureAwait(false); }