/// <summary>
        /// Add a cache handle configuration with the required name and type attributes.
        /// </summary>
        /// <param name="cacheHandleBaseType">The handle's type without generic attribute.</param>
        /// <param name="handleName">The name to be used for the cache handle.</param>
        /// <param name="isBackPlateSource">
        /// Set this to true if this cache handle should be the source of the back plate.
        /// <para>This setting will be ignored if no back plate is configured.</para>
        /// </param>
        /// <returns>The builder part.</returns>
        /// <exception cref="System.ArgumentNullException">If handleName is null.</exception>
        /// <exception cref="System.InvalidOperationException">
        /// Only one cache handle can be the backplate's source.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Thrown if handleName or cacheHandleBaseType are null.
        /// </exception>
        public ConfigurationBuilderCacheHandlePart WithHandle(Type cacheHandleBaseType, string handleName, bool isBackPlateSource)
        {
            if (cacheHandleBaseType == null)
            {
                throw new ArgumentNullException("cacheHandleBaseType");
            }

            if (string.IsNullOrWhiteSpace(handleName))
            {
                throw new ArgumentNullException("handleName");
            }

            var handleCfg = new CacheHandleConfiguration(handleName)
            {
                HandleType = cacheHandleBaseType
            };

            handleCfg.IsBackPlateSource = isBackPlateSource;

            if (this.Configuration.CacheHandleConfigurations.Any(p => p.IsBackPlateSource))
            {
                throw new InvalidOperationException("Only one cache handle can be the back plate's source.");
            }

            this.Configuration.CacheHandleConfigurations.Add(handleCfg);
            var part = new ConfigurationBuilderCacheHandlePart(handleCfg, this);

            return(part);
        }
        private static CacheHandleConfiguration GetHandleFromConfiguration(IConfigurationSection handleConfiguration)
        {
            var type      = handleConfiguration[ConfigurationType];
            var knownType = handleConfiguration[ConfigurationKnownType];
            var key       = handleConfiguration[ConfigurationKey] ?? handleConfiguration[ConfigurationName]; // name fallback for key
            var name      = handleConfiguration[ConfigurationName];

            var cacheHandleConfiguration = new CacheHandleConfiguration();

            handleConfiguration.Bind(cacheHandleConfiguration);
            cacheHandleConfiguration.Key  = key;
            cacheHandleConfiguration.Name = name ?? cacheHandleConfiguration.Name;

            if (string.IsNullOrEmpty(type) && string.IsNullOrEmpty(knownType))
            {
                throw new InvalidOperationException(
                          $"No '{ConfigurationType}' or '{ConfigurationKnownType}' defined in cache handle configuration '{handleConfiguration.Path}'.");
            }

            if (string.IsNullOrWhiteSpace(type))
            {
                var keyRequired = false;
                cacheHandleConfiguration.HandleType = GetKnownHandleType(knownType, handleConfiguration.Path, out keyRequired);

                // some handles require name or key to be set to link to other parts of the configuration
                // lets check if that condition is satisfied
                if (keyRequired && string.IsNullOrWhiteSpace(key) && string.IsNullOrWhiteSpace(name))
                {
                    throw new InvalidOperationException(
                              $@"Known handle of type '{knownType}' requires '{ConfigurationKey}' or '{ConfigurationName}' to be defined.
                            Check configuration at '{handleConfiguration.Path}'.");
                }
            }
            else
            {
                cacheHandleConfiguration.HandleType = Type.GetType(type, true);
            }

            return(cacheHandleConfiguration);
        }
예제 #3
0
        /// <summary>
        /// Adds a cache handle with the given <c>Type</c> and name.
        /// The type must be an open generic.
        /// </summary>
        /// <param name="cacheHandleBaseType">The cache handle type.</param>
        /// <param name="handleName">The name to be used for the cache handle.</param>
        /// <param name="isBackplaneSource">
        /// Set this to true if this cache handle should be the source of the backplane.
        /// <para>This setting will be ignored if no backplane is configured.</para>
        /// </param>
        /// <returns>The builder part.</returns>
        /// <exception cref="System.ArgumentNullException">If handleName is null.</exception>
        /// <exception cref="System.InvalidOperationException">
        /// Only one cache handle can be the backplane's source.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Thrown if handleName or cacheHandleBaseType are null.
        /// </exception>
        public ConfigurationBuilderCacheHandlePart WithHandle(Type cacheHandleBaseType, string handleName, bool isBackplaneSource)
        {
            NotNull(cacheHandleBaseType, nameof(cacheHandleBaseType));
            NotNullOrWhiteSpace(handleName, nameof(handleName));

            var handleCfg = new CacheHandleConfiguration(handleName)
            {
                HandleType = cacheHandleBaseType
            };

            handleCfg.IsBackplaneSource = isBackplaneSource;

            if (isBackplaneSource && this.Configuration.CacheHandleConfigurations.Any(p => p.IsBackplaneSource))
            {
                throw new InvalidOperationException("Only one cache handle can be the backplane's source.");
            }

            this.Configuration.CacheHandleConfigurations.Add(handleCfg);
            var part = new ConfigurationBuilderCacheHandlePart(handleCfg, this);

            return(part);
        }
예제 #4
0
        /// <summary>
        /// Adds a cache handle with the given <c>Type</c> and name.
        /// The type must be an open generic.
        /// </summary>
        /// <param name="cacheHandleBaseType">The cache handle type.</param>
        /// <param name="handleName">The name to be used for the cache handle.</param>
        /// <param name="isBackplaneSource">
        /// Set this to true if this cache handle should be the source of the backplane.
        /// <para>This setting will be ignored if no backplane is configured.</para>
        /// </param>
        /// <returns>The builder part.</returns>
        /// <exception cref="System.ArgumentNullException">If handleName is null.</exception>
        /// <exception cref="System.InvalidOperationException">
        /// Only one cache handle can be the backplane's source.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Thrown if handleName or cacheHandleBaseType are null.
        /// </exception>
        public ConfigurationBuilderCacheHandlePart WithHandle(Type cacheHandleBaseType, string handleName, bool isBackplaneSource)
        {
            NotNull(cacheHandleBaseType, nameof(cacheHandleBaseType));
            NotNullOrWhiteSpace(handleName, nameof(handleName));

            var handleCfg = new CacheHandleConfiguration(handleName)
            {
                HandleType = cacheHandleBaseType
            };

            handleCfg.IsBackplaneSource = isBackplaneSource;

            if (isBackplaneSource && this.Configuration.CacheHandleConfigurations.Any(p => p.IsBackplaneSource))
            {
                throw new InvalidOperationException("Only one cache handle can be the backplane's source.");
            }

            this.Configuration.CacheHandleConfigurations.Add(handleCfg);
            var part = new ConfigurationBuilderCacheHandlePart(handleCfg, this);
            return part;
        }
예제 #5
0
 internal ConfigurationBuilderCacheHandlePart(CacheHandleConfiguration cfg, ConfigurationBuilderCachePart parentPart)
 {
     this.Configuration = cfg;
     this.parent = parentPart;
 }
예제 #6
0
        internal static CacheManagerConfiguration LoadFromSection(CacheManagerSection section, string configName)
        {
            NotNullOrWhiteSpace(configName, nameof(configName));

            var handleDefsSection = section.CacheHandleDefinitions;

            Ensure(handleDefsSection.Count > 0, "There are no cache handles defined.");

            // load handle definitions as lookup
            var handleDefs = new SortedList<string, CacheHandleConfiguration>();
            foreach (CacheHandleDefinition def in handleDefsSection)
            {
                //// don't validate at this point, otherwise we will get an exception if any defined handle doesn't match with the requested type...
                //// CacheReflectionHelper.ValidateCacheHandleGenericTypeArguments(def.HandleType, cacheValue);

                var normId = def.Id.ToUpper(CultureInfo.InvariantCulture);
                handleDefs.Add(
                    normId,
                    new CacheHandleConfiguration(def.Id)
                    {
                        HandleType = def.HandleType,
                        ExpirationMode = def.DefaultExpirationMode,
                        ExpirationTimeout = GetTimeSpan(def.DefaultTimeout, "defaultTimeout")
                    });
            }

            // retrieve the handles collection with the correct name
            CacheManagerHandleCollection managerCfg = section.CacheManagers.FirstOrDefault(p => p.Name.Equals(configName, StringComparison.OrdinalIgnoreCase));

            EnsureNotNull(managerCfg, "No cache manager configuration found for name [{0}]", configName);

            int? maxRetries = managerCfg.MaximumRetries;
            if (maxRetries.HasValue && maxRetries.Value <= 0)
            {
                throw new InvalidOperationException("Maximum number of retries must be greater than zero.");
            }

            int? retryTimeout = managerCfg.RetryTimeout;
            if (retryTimeout.HasValue && retryTimeout.Value < 0)
            {
                throw new InvalidOperationException("Retry timeout must be greater than or equal to zero.");
            }

            // build configuration
            var cfg = new CacheManagerConfiguration()
            {
                UpdateMode = managerCfg.UpdateMode,
                MaxRetries = maxRetries.HasValue ? maxRetries.Value : 50,
                RetryTimeout = retryTimeout.HasValue ? retryTimeout.Value : 100
            };

            if (string.IsNullOrWhiteSpace(managerCfg.BackplaneType))
            {
                if (!string.IsNullOrWhiteSpace(managerCfg.BackplaneName))
                {
                    throw new InvalidOperationException("Backplane type cannot be null if backplane name is specified.");
                }
            }
            else
            {
                if (string.IsNullOrWhiteSpace(managerCfg.BackplaneName))
                {
                    throw new InvalidOperationException("Backplane name cannot be null if backplane type is specified.");
                }

                var backplaneType = Type.GetType(managerCfg.BackplaneType, false);
                EnsureNotNull(backplaneType, "Backplane type not found, '{0}'. Make sure to install the corresponding nuget package.", managerCfg.BackplaneType);

                cfg.BackplaneType = backplaneType;
                cfg.BackplaneConfigurationKey = managerCfg.BackplaneName;
            }

            // build serializer if set
            if (!string.IsNullOrWhiteSpace(managerCfg.SerializerType))
            {
                var serializerType = Type.GetType(managerCfg.SerializerType, false);
                EnsureNotNull(serializerType, "Serializer type not found, {0}.", managerCfg.SerializerType);

                cfg.SerializerType = serializerType;
            }

            foreach (CacheManagerHandle handleItem in managerCfg)
            {
                var normRefId = handleItem.RefHandleId.ToUpper(CultureInfo.InvariantCulture);

                Ensure(
                    handleDefs.ContainsKey(normRefId),
                    "Referenced cache handle [{0}] cannot be found in cache handles definition.",
                    handleItem.RefHandleId);

                var handleDef = handleDefs[normRefId];

                var handle = new CacheHandleConfiguration(handleItem.Name)
                {
                    HandleType = handleDef.HandleType,
                    ExpirationMode = handleDef.ExpirationMode,
                    ExpirationTimeout = handleDef.ExpirationTimeout,
                    EnableStatistics = managerCfg.EnableStatistics,
                    EnablePerformanceCounters = managerCfg.EnablePerformanceCounters,
                    IsBackplaneSource = handleItem.IsBackplaneSource
                };

                // override default timeout if it is defined in this section.
                if (!string.IsNullOrWhiteSpace(handleItem.Timeout))
                {
                    handle.ExpirationTimeout = GetTimeSpan(handleItem.Timeout, "timeout");
                }

                // override default expiration mode if it is defined in this section.
                if (!string.IsNullOrWhiteSpace(handleItem.ExpirationMode))
                {
                    try
                    {
                        handle.ExpirationMode = (ExpirationMode)Enum.Parse(typeof(ExpirationMode), handleItem.ExpirationMode);
                    }
                    catch (ArgumentException ex)
                    {
                        throw new InvalidOperationException("Invalid value '" + handleItem.ExpirationMode + "'for expiration mode", ex);
                    }
                }

                if (handle.ExpirationMode != ExpirationMode.None && handle.ExpirationTimeout == TimeSpan.Zero)
                {
                    throw new InvalidOperationException(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "Expiration mode set without a valid timeout specified for handle [{0}]",
                            handle.Name));
                }

                cfg.CacheHandleConfigurations.Add(handle);
            }

            Ensure(cfg.CacheHandleConfigurations.Count > 0, "There are no valid cache handles linked to the cache manager configuration [{0}]", configName);

            return cfg;
        }
 internal ConfigurationBuilderCacheHandlePart(CacheHandleConfiguration cfg, ConfigurationBuilderCachePart parentPart)
 {
     Configuration = cfg;
     _parent       = parentPart;
 }
        internal static CacheManagerConfiguration LoadFromSection(CacheManagerSection section, string configName)
        {
            NotNullOrWhiteSpace(configName, nameof(configName));

            var handleDefsSection = section.CacheHandleDefinitions;

            Ensure(handleDefsSection.Count > 0, "There are no cache handles defined.");

            // load handle definitions as lookup
            var handleDefs = new SortedList <string, CacheHandleConfiguration>();

            foreach (var def in handleDefsSection)
            {
                //// don't validate at this point, otherwise we will get an exception if any defined handle doesn't match with the requested type...
                //// CacheReflectionHelper.ValidateCacheHandleGenericTypeArguments(def.HandleType, cacheValue);

                var normId = def.Id.ToUpper(CultureInfo.InvariantCulture);
                handleDefs.Add(
                    normId,
                    new CacheHandleConfiguration(def.Id)
                {
                    HandleType        = def.HandleType,
                    ExpirationMode    = def.DefaultExpirationMode,
                    ExpirationTimeout = GetTimeSpan(def.DefaultTimeout, "defaultTimeout")
                });
            }

            // retrieve the handles collection with the correct name
            var managerCfg = section.CacheManagers.FirstOrDefault(p => p.Name.Equals(configName, StringComparison.OrdinalIgnoreCase));

            EnsureNotNull(managerCfg, "No cache manager configuration found for name [{0}]", configName);

            var maxRetries = managerCfg.MaximumRetries;

            if (maxRetries.HasValue && maxRetries.Value <= 0)
            {
                throw new InvalidOperationException("Maximum number of retries must be greater than zero.");
            }

            var retryTimeout = managerCfg.RetryTimeout;

            if (retryTimeout.HasValue && retryTimeout.Value < 0)
            {
                throw new InvalidOperationException("Retry timeout must be greater than or equal to zero.");
            }

            // build configuration
            var cfg = new CacheManagerConfiguration()
            {
                UpdateMode   = managerCfg.UpdateMode,
                MaxRetries   = maxRetries ?? 50,
                RetryTimeout = retryTimeout ?? 100
            };

            if (string.IsNullOrWhiteSpace(managerCfg.BackplaneType))
            {
                if (!string.IsNullOrWhiteSpace(managerCfg.BackplaneName))
                {
                    throw new InvalidOperationException("Backplane type cannot be null if backplane name is specified.");
                }
            }
            else
            {
                if (string.IsNullOrWhiteSpace(managerCfg.BackplaneName))
                {
                    throw new InvalidOperationException("Backplane name cannot be null if backplane type is specified.");
                }

                var backplaneType = Type.GetType(managerCfg.BackplaneType, false);
                EnsureNotNull(backplaneType, "Backplane type not found, '{0}'. Make sure to install the corresponding nuget package.", managerCfg.BackplaneType);

                cfg.BackplaneType             = backplaneType;
                cfg.BackplaneConfigurationKey = managerCfg.BackplaneName;
            }

            // build serializer if set
            if (!string.IsNullOrWhiteSpace(managerCfg.SerializerType))
            {
                var serializerType = Type.GetType(managerCfg.SerializerType, false);
                EnsureNotNull(serializerType, "Serializer type not found, {0}.", managerCfg.SerializerType);

                cfg.SerializerType = serializerType;
            }

            foreach (var handleItem in managerCfg)
            {
                var normRefId = handleItem.RefHandleId.ToUpper(CultureInfo.InvariantCulture);

                Ensure(
                    handleDefs.ContainsKey(normRefId),
                    "Referenced cache handle [{0}] cannot be found in cache handles definition.",
                    handleItem.RefHandleId);

                var handleDef = handleDefs[normRefId];

                var handle = new CacheHandleConfiguration(handleItem.Name)
                {
                    HandleType                = handleDef.HandleType,
                    ExpirationMode            = handleDef.ExpirationMode,
                    ExpirationTimeout         = handleDef.ExpirationTimeout,
                    EnableStatistics          = managerCfg.EnableStatistics,
                    EnablePerformanceCounters = managerCfg.EnablePerformanceCounters,
                    IsBackplaneSource         = handleItem.IsBackplaneSource
                };

                // override default timeout if it is defined in this section.
                if (!string.IsNullOrWhiteSpace(handleItem.Timeout))
                {
                    handle.ExpirationTimeout = GetTimeSpan(handleItem.Timeout, "timeout");
                }

                // override default expiration mode if it is defined in this section.
                if (!string.IsNullOrWhiteSpace(handleItem.ExpirationMode))
                {
                    try
                    {
                        handle.ExpirationMode = (ExpirationMode)Enum.Parse(typeof(ExpirationMode), handleItem.ExpirationMode);
                    }
                    catch (ArgumentException ex)
                    {
                        throw new InvalidOperationException("Invalid value '" + handleItem.ExpirationMode + "'for expiration mode", ex);
                    }
                }

                if (handle.ExpirationMode != ExpirationMode.None && handle.ExpirationTimeout == TimeSpan.Zero)
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  CultureInfo.InvariantCulture,
                                  "Expiration mode set without a valid timeout specified for handle [{0}]",
                                  handle.Name));
                }

                cfg.CacheHandleConfigurations.Add(handle);
            }

            Ensure(cfg.CacheHandleConfigurations.Count > 0, "There are no valid cache handles linked to the cache manager configuration [{0}]", configName);

            return(cfg);
        }
        private static CacheHandleConfiguration GetHandleFromConfiguration(IConfigurationSection handleConfiguration)
        {
            var type = handleConfiguration[ConfigurationType];
            var knownType = handleConfiguration[ConfigurationKnownType];
            var key = handleConfiguration[ConfigurationKey] ?? handleConfiguration[ConfigurationName];    // name fallback for key
            var name = handleConfiguration[ConfigurationName];

            var cacheHandleConfiguration = new CacheHandleConfiguration();
            handleConfiguration.Bind(cacheHandleConfiguration);
            cacheHandleConfiguration.Key = key;
            cacheHandleConfiguration.Name = name ?? cacheHandleConfiguration.Name;

            if (string.IsNullOrEmpty(type) && string.IsNullOrEmpty(knownType))
            {
                throw new InvalidOperationException(
                    $"No '{ConfigurationType}' or '{ConfigurationKnownType}' defined in cache handle configuration '{handleConfiguration.Path}'.");
            }

            if (string.IsNullOrWhiteSpace(type))
            {
                var keyRequired = false;
                cacheHandleConfiguration.HandleType = GetKnownHandleType(knownType, handleConfiguration.Path, out keyRequired);

                // some handles require name or key to be set to link to other parts of the configuration
                // lets check if that condition is satisfied
                if (keyRequired && string.IsNullOrWhiteSpace(key) && string.IsNullOrWhiteSpace(name))
                {
                    throw new InvalidOperationException(
                        $@"Known handle of type '{knownType}' requires '{ConfigurationKey}' or '{ConfigurationName}' to be defined.
                            Check configuration at '{handleConfiguration.Path}'.");
                }
            }
            else
            {
                cacheHandleConfiguration.HandleType = Type.GetType(type, true);
            }

            return cacheHandleConfiguration;
        }