private void AddEntityPlaceholder(ReactiveEntityKind kind, string key) { var uri = new Uri(key); #pragma warning disable IDE0079 // Remove unnecessary suppression. #pragma warning disable CA2000 // Dispose objects before losing scope. (Entities are owned by the registry.) var added = kind switch { ReactiveEntityKind.Observable => Registry.Observables.TryAdd(key, ObservableDefinitionEntity.CreateInvalidInstance(uri)), ReactiveEntityKind.Observer => Registry.Observers.TryAdd(key, ObserverDefinitionEntity.CreateInvalidInstance(uri)), ReactiveEntityKind.Stream => Registry.Subjects.TryAdd(key, SubjectEntity.CreateInvalidInstance(uri)), ReactiveEntityKind.StreamFactory => Registry.SubjectFactories.TryAdd(key, StreamFactoryDefinitionEntity.CreateInvalidInstance(uri)), ReactiveEntityKind.SubscriptionFactory => Registry.SubscriptionFactories.TryAdd(key, SubscriptionFactoryDefinitionEntity.CreateInvalidInstance(uri)), ReactiveEntityKind.Subscription => Registry.Subscriptions.TryAdd(key, SubscriptionEntity.CreateInvalidInstance(uri)), ReactiveEntityKind.ReliableSubscription => Registry.ReliableSubscriptions.TryAdd(key, ReliableSubscriptionEntity.CreateInvalidInstance(uri)), ReactiveEntityKind.Other => Registry.Other.TryAdd(key, OtherDefinitionEntity.CreateInvalidInstance(uri)), ReactiveEntityKind.Template => Registry.Templates.TryAdd(key, OtherDefinitionEntity.CreateInvalidInstance(uri)), _ => throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Cannot create an invalid entity '{0}' of type '{1}'.", key, kind)), }; #pragma warning restore CA2000 #pragma warning restore IDE0079 if (added) { Parent.TraceSource.Registry_AddEntityPlaceholder(Parent.Uri, kind.ToString(), key); } }
/// <summary> /// Creates an invalid instance of the given reactive entity kind with the given URI. /// </summary> /// <param name="uri">The URI.</param> /// <param name="kind">The reactive entity kind.</param> /// <returns> /// The invalid instance, or null if an unexpected kind is provided. /// </returns> public static ReactiveEntity CreateInvalidInstance(Uri uri, ReactiveEntityKind kind) { return(kind switch { ReactiveEntityKind.Observable => ObservableDefinitionEntity.CreateInvalidInstance(uri), ReactiveEntityKind.Observer => ObserverDefinitionEntity.CreateInvalidInstance(uri), ReactiveEntityKind.Stream => SubjectEntity.CreateInvalidInstance(uri), ReactiveEntityKind.StreamFactory => StreamFactoryDefinitionEntity.CreateInvalidInstance(uri), ReactiveEntityKind.Subscription => SubscriptionEntity.CreateInvalidInstance(uri), ReactiveEntityKind.ReliableSubscription => ReliableSubscriptionEntity.CreateInvalidInstance(uri), ReactiveEntityKind.Template or ReactiveEntityKind.Other => OtherDefinitionEntity.CreateInvalidInstance(uri), _ => null, });
/// <summary> /// Templatize an expression, using an existing template in the /// query engine registry if possible. Otherwise, if no template /// exists yet, add a new entry to the registry as a side-effect. /// </summary> /// <param name="expression">The original expression.</param> /// <returns>The templatized expression.</returns> /// <remarks> /// If the expression does not contain any constants, the original /// expression will be returned unchanged. /// </remarks> public virtual Expression Templatize(Expression expression) { var appliedTemplate = expression.TemplatizeAndIdentify(); var templatized = appliedTemplate.Expression; // If the expression has been templatized, it will differ from the original if (expression != templatized) { #pragma warning disable IDE0079 // Remove unnecessary suppression. #pragma warning disable CA2000 // Dispose objects before losing scope. (Entity will be owned by the registry after operation completes; otherwise, its Dispose is unnecessary.) var templateEntity = new OtherDefinitionEntity(new Uri(appliedTemplate.TemplateId), appliedTemplate.Template, state: null); // Check if the template already exists using the inverted entity collection var updateTemplate = true; if (!_registry.Templates.TryGetKey(templateEntity, out string templateId)) { // Try to add the template, note there is a race here. templateId = templateEntity.Uri.ToCanonicalString(); updateTemplate = false; if (!_registry.Templates.TryAdd(templateId, templateEntity)) { // Lost the race, grab the template that was just added. updateTemplate = true; var found = _registry.Templates.TryGetKey(templateEntity, out templateId); Debug.Assert(found); } } #pragma warning restore CA2000 #pragma warning restore IDE0079 if (updateTemplate) { templatized = templatized.SubstituteTemplateId(templateId); } } return(templatized); }