/// <summary> /// Unifies generic types with awareness of the conversion from asynchronous to synchronous Reactive entity types. /// </summary> /// <param name="typeRich">The CLR type.</param> /// <param name="typeSlim">The slim type.</param> /// <returns>true if the unification was successful, false otherwise.</returns> protected override bool UnifyGeneric(Type typeRich, GenericTypeSlim typeSlim) { var reactiveType = ReactiveEntityTypeExtensions.FromTypeSlim(typeSlim); if ((reactiveType & ReactiveEntityType.Func) == ReactiveEntityType.Func) { reactiveType = ReactiveEntityType.Func; } return(reactiveType switch { ReactiveEntityType.Func => Unify(typeRich.GetGenericArguments(), typeSlim), ReactiveEntityType.Observer or ReactiveEntityType.Observable or ReactiveEntityType.StreamFactory or ReactiveEntityType.SubscriptionFactory or ReactiveEntityType.Stream => Unify(GetEntityTypes(typeRich, reactiveType), typeSlim), _ => base.UnifyGeneric(typeRich, typeSlim), });
/// <summary> /// Looks up the free variable name in the Reactive metadata and attempts to unify entity types. /// </summary> /// <param name="free">The free variable.</param> /// <param name="metadata">The metadata to unify aginst.</param> /// <returns> /// Unifications between the free variable type and the known resource type. /// </returns> internal static IEnumerable <KeyValuePair <TypeSlim, Type> > FindAndUnify(ParameterExpressionSlim free, IReactiveMetadata metadata) { var reactiveType = ReactiveEntityTypeExtensions.FromTypeSlim(free.Type); if ((reactiveType & ReactiveEntityType.Func) == ReactiveEntityType.Func) { reactiveType ^= ReactiveEntityType.Func; } var metadataType = default(Type); switch (reactiveType) { case ReactiveEntityType.Observer: if (metadata.Observers.TryGetValue(new Uri(free.Name), out var observer)) { metadataType = observer.Expression.Type; } break; case ReactiveEntityType.Observable: if (metadata.Observables.TryGetValue(new Uri(free.Name), out var observable)) { metadataType = observable.Expression.Type; } break; case ReactiveEntityType.SubscriptionFactory: if (metadata.SubscriptionFactories.TryGetValue(new Uri(free.Name), out var subscriptionFactory)) { metadataType = subscriptionFactory.Expression.Type; } break; case ReactiveEntityType.Subscription: if (metadata.Subscriptions.TryGetValue(new Uri(free.Name), out var subscription)) { metadataType = subscription.Expression.Type; } break; case ReactiveEntityType.StreamFactory: if (metadata.StreamFactories.TryGetValue(new Uri(free.Name), out var streamFactory)) { metadataType = streamFactory.Expression.Type; } break; case ReactiveEntityType.Stream: if (metadata.Streams.TryGetValue(new Uri(free.Name), out var stream)) { metadataType = stream.Expression.Type; } break; } if (metadataType != null) { var unifier = new DataModelTypeUnifier(); if (unifier.Unify(metadataType, free.Type)) { return(unifier.Entries); } } return(Array.Empty <KeyValuePair <TypeSlim, Type> >()); }
private static void AssertType(ReactiveEntityType reactiveType, Type type) { Assert.AreEqual(reactiveType, ReactiveEntityTypeExtensions.FromType(type)); Assert.AreEqual(reactiveType, ReactiveEntityTypeExtensions.FromTypeSlim(type.ToTypeSlim())); }