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);
                }
            }
예제 #2
0
 /// <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);
        }