/// <summary> /// Returns the <see cref="GrainType"/> which supports the provided <see cref="GrainInterfaceType"/> and which has an implementing type name beginning with the provided prefix string. /// </summary> public GrainType GetGrainType(GrainInterfaceType interfaceType, string prefix) { if (string.IsNullOrWhiteSpace(prefix)) { return(GetGrainType(interfaceType)); } GrainType result = default; GrainInterfaceType lookupType; if (GenericGrainInterfaceType.TryParse(interfaceType, out var genericInterface)) { lookupType = genericInterface.GetGenericGrainType().Value; } else { lookupType = interfaceType; } var cache = GetCache(); if (cache.Map.TryGetValue(lookupType, out var entry)) { var hasCandidate = false; foreach (var impl in entry.Implementations) { if (impl.Prefix.StartsWith(prefix, StringComparison.Ordinal)) { if (impl.Prefix.Length == prefix.Length) { // Exact matches take precedence result = impl.GrainType; break; } if (hasCandidate) { var candidates = string.Join(", ", entry.Implementations.Select(i => $"{i.GrainType} ({i.Prefix})")); throw new ArgumentException($"Unable to identify a single appropriate grain type for interface {interfaceType} with implementation prefix \"{prefix}\". Candidates: {candidates}"); } result = impl.GrainType; hasCandidate = true; } } } if (result.IsDefault) { throw new ArgumentException($"Could not find an implementation matching prefix \"{prefix}\" for interface {interfaceType}"); } if (GenericGrainType.TryParse(result, out var genericGrainType) && !genericGrainType.IsConstructed) { result = genericGrainType.GrainType.GetConstructed(genericInterface.Value); } return(result); }
/// <summary> /// Gets the grain properties for the provided type. /// </summary> public bool TryGetGrainProperties(GrainType grainType, out GrainProperties properties) { var clusterManifest = _clusterManifestProvider.Current; if (clusterManifest is null) { properties = default; return(false); } GrainType lookupKey; if (GenericGrainType.TryParse(grainType, out var generic)) { lookupKey = generic.GetUnconstructedGrainType().GrainType; } else { lookupKey = grainType; } foreach (var manifest in clusterManifest.AllGrainManifests) { if (manifest.Grains.TryGetValue(lookupKey, out properties)) { return(true); } } properties = default; return(false); }
/// <summary> /// Returns the grain class type corresponding to the provided grain type. /// </summary> public bool TryGetGrainClass(GrainType grainType, out Type grainClass) { GrainType lookupType; Type[] args; if (GenericGrainType.TryParse(grainType, out var genericId)) { lookupType = genericId.GetUnconstructedGrainType().GrainType; args = genericId.GetArguments(_typeConverter); } else { lookupType = grainType; args = default; } if (!_types.TryGetValue(lookupType, out grainClass)) { return(false); } if (args is object) { grainClass = grainClass.MakeGenericType(args); } return(true); }
/// <summary> /// Gets bindings for the provided grain type. /// </summary> public GrainBindings GetBindings(GrainType grainType) { GrainType lookupType; if (GenericGrainType.TryParse(grainType, out var generic)) { if (!_genericMapping.TryGetValue(generic, out lookupType)) { lookupType = _genericMapping[generic] = generic.GetUnconstructedGrainType().GrainType; } } else { lookupType = grainType; } var cache = GetCache(); if (cache.Map.TryGetValue(lookupType, out var result)) { return(result); } return(new GrainBindings(grainType, ImmutableArray <ImmutableDictionary <string, string> > .Empty)); }
/// <summary> /// Returns a <see cref="GrainType"/> which implements the provided <see cref="GrainInterfaceType"/>. /// </summary> public GrainType GetGrainType(GrainInterfaceType interfaceType) { GrainType result = default; var cache = GetCache(); if (cache.Map.TryGetValue(interfaceType, out var entry)) { if (!entry.PrimaryImplementation.IsDefault) { result = entry.PrimaryImplementation; } else if (entry.Implementations.Count == 1) { result = entry.Implementations[0].GrainType; } else if (entry.Implementations.Count > 1) { var candidates = string.Join(", ", entry.Implementations.Select(i => $"{i.GrainType} ({i.Prefix})")); throw new ArgumentException($"Unable to identify a single appropriate grain type for interface {interfaceType}. Candidates: {candidates}"); } else { // No implementations } } else if (_genericMapping.TryGetValue(interfaceType, out result)) { } else if (GenericGrainInterfaceType.TryParse(interfaceType, out var genericInterface)) { var unconstructedInterface = genericInterface.GetGenericGrainType(); var unconstructed = GetGrainType(unconstructedInterface.Value); if (GenericGrainType.TryParse(unconstructed, out var genericGrainType)) { if (genericGrainType.IsConstructed) { result = genericGrainType.GrainType; } else { result = genericGrainType.GrainType.GetConstructed(genericInterface.Value); } } else { result = unconstructed; } _genericMapping[interfaceType] = result; } if (result.IsDefault) { throw new ArgumentException($"Could not find an implementation for interface {interfaceType}"); } return(result); }
private GrainType AddGenericParameters(GrainType grainType, Type type) { if (GenericGrainType.TryParse(grainType, out var genericGrainType) && type.IsConstructedGenericType && !type.ContainsGenericParameters && !genericGrainType.IsConstructed) { grainType = genericGrainType.Construct(_typeConverter, type.GetGenericArguments()).GrainType; } return(grainType); }
public bool TryResolveGrainDirectory(GrainType grainType, GrainProperties properties, out IGrainDirectory grainDirectory) { if (GenericGrainType.TryParse(grainType, out var constructed) && constructed.IsConstructed) { var generic = constructed.GetUnconstructedGrainType().GrainType; var resolver = GetResolver(); if (resolver.TryGetNonDefaultGrainDirectory(generic, out grainDirectory)) { return(true); } } grainDirectory = default; return(false); }
public void ReubensGenericGrainIdTest() { var genericType = GrainType.Create("foo`1"); var services = ((InProcessSiloHandle)this.Fixture.HostedCluster.Primary).SiloHost.Services; var resolver = services.GetRequiredService <PlacementStrategyResolver>(); var t = resolver.GetPlacementStrategy(genericType); Assert.NotNull(t); Assert.True(GenericGrainType.TryParse(genericType, out var g)); Assert.False(g.IsConstructed); var formatter = services.GetRequiredService <TypeConverter>(); var c = g.Construct(formatter, typeof(int)); var t2 = resolver.GetPlacementStrategy(c.GrainType); Assert.NotNull(t2); }
public (MajorMinorVersion Version, SiloAddress[] Result) GetSupportedSilos(GrainType grainType) { var cache = GetCache(); if (cache.SupportedSilosByGrainType.TryGetValue(grainType, out var result)) { return(cache.Version, result); } if (_genericGrainTypeMapping.TryGetValue(grainType, out var genericGrainType)) { return(GetSupportedSilos(genericGrainType)); } if (GenericGrainType.TryParse(grainType, out var generic) && generic.IsConstructed) { var genericId = _genericGrainTypeMapping[grainType] = generic.GetUnconstructedGrainType().GrainType; return(GetSupportedSilos(genericId)); } // No supported silos for this type. return(cache.Version, Array.Empty <SiloAddress>()); }