private Cache BuildCache(MajorMinorVersion version, ImmutableDictionary <GrainType, GrainBindings> bindings) { var newPredicates = new List <BroadcastChannelSubscriberPredicate>(); foreach (var binding in bindings.Values) { foreach (var grainBinding in binding.Bindings) { if (!grainBinding.TryGetValue(WellKnownGrainTypeProperties.BindingTypeKey, out var type) || !string.Equals(type, WellKnownGrainTypeProperties.BroadcastChannelBindingTypeValue, StringComparison.Ordinal)) { continue; } if (!grainBinding.TryGetValue(WellKnownGrainTypeProperties.BroadcastChannelBindingPatternKey, out var pattern)) { throw new KeyNotFoundException( $"Channel binding for grain type {binding.GrainType} is missing a \"{WellKnownGrainTypeProperties.BroadcastChannelBindingPatternKey}\" value"); } IChannelNamespacePredicate predicate = null; foreach (var provider in _providers) { if (provider.TryGetPredicate(pattern, out predicate)) { break; } } if (predicate is null) { throw new KeyNotFoundException( $"Could not find an {nameof(IChannelNamespacePredicate)} for the pattern \"{pattern}\"." + $" Ensure that a corresponding {nameof(IChannelNamespacePredicateProvider)} is registered"); } if (!grainBinding.TryGetValue(WellKnownGrainTypeProperties.ChannelIdMapperKey, out var mapperName)) { throw new KeyNotFoundException( $"Channel binding for grain type {binding.GrainType} is missing a \"{WellKnownGrainTypeProperties.ChannelIdMapperKey}\" value"); } var channelIdMapper = _serviceProvider.GetServiceByName <IChannelIdMapper>(string.IsNullOrWhiteSpace(mapperName) ? DefaultChannelIdMapper.Name : mapperName); var subscriber = new BroadcastChannelSubscriber(binding, channelIdMapper); newPredicates.Add(new BroadcastChannelSubscriberPredicate(subscriber, predicate)); } } return(new Cache(version, newPredicates)); }
/// <inheritdoc/> public bool TryGetPredicate(string predicatePattern, out IChannelNamespacePredicate predicate) { switch (predicatePattern) { case "*": predicate = new AllStreamNamespacesPredicate(); return(true); case var regex when regex.StartsWith(RegexChannelNamespacePredicate.Prefix, StringComparison.Ordinal): predicate = new RegexChannelNamespacePredicate(regex.Substring(RegexChannelNamespacePredicate.Prefix.Length)); return(true); case var ns when ns.StartsWith(ExactMatchChannelNamespacePredicate.Prefix, StringComparison.Ordinal): predicate = new ExactMatchChannelNamespacePredicate(ns.Substring(ExactMatchChannelNamespacePredicate.Prefix.Length)); return(true); } predicate = null; return(false); }
/// <inheritdoc/> public bool TryGetPredicate(string predicatePattern, out IChannelNamespacePredicate predicate) { if (!predicatePattern.StartsWith(Prefix, StringComparison.Ordinal)) { predicate = null; return(false); } var start = Prefix.Length + 1; string typeName; string arg; var index = predicatePattern.IndexOf(':', start); if (index < 0) { typeName = predicatePattern.Substring(start); arg = null; } else { typeName = predicatePattern.Substring(start, index - start); arg = predicatePattern.Substring(index + 1); } var type = Type.GetType(typeName, throwOnError: true); if (string.IsNullOrEmpty(arg)) { predicate = (IChannelNamespacePredicate)Activator.CreateInstance(type); } else { predicate = (IChannelNamespacePredicate)Activator.CreateInstance(type, arg); } return(true); }
public BroadcastChannelSubscriberPredicate(BroadcastChannelSubscriber subscriber, IChannelNamespacePredicate predicate) { Subscriber = subscriber; Predicate = predicate; }
/// <summary> /// Allows to pass an instance of the stream namespace predicate. To be used mainly as an extensibility point /// via inheriting attributes. /// </summary> /// <param name="predicate">The stream namespace predicate.</param> /// <param name="channelIdMapper">The name of the stream identity mapper.</param> public ImplicitChannelSubscriptionAttribute(IChannelNamespacePredicate predicate, string channelIdMapper = null) { Predicate = predicate; ChannelIdMapper = channelIdMapper; }