Skip to content

Instantly share code, notes, and snippets.

@abombss
Last active January 1, 2016 13:59
Show Gist options
  • Save abombss/8154959 to your computer and use it in GitHub Desktop.
Save abombss/8154959 to your computer and use it in GitHub Desktop.
NServiceBus.Override to easily override configuration sections, and sources at runtime.
#region Copyright
//The MIT License (MIT)
//
//Copyright (c) 2013 Adam Tybor (adam.tybor@gmail.com)
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
#endregion
namespace NServiceBus
{
using System;
using System.Configuration;
using global::NServiceBus.Config.ConfigurationSource;
using global::NServiceBus.Override;
public static class OverrideExtensions
{
/// <summary>
/// Easily override configuration section values in code. This will also preserve any custom configuration sources that were set.
/// If the current config source is null, then it will instantiate a new DefaultConfigurationSource
/// so make sure to call config.CustomConfigurationSource first if you don't want the default configuration
/// source being used.
/// </summary>
/// <typeparam name="T">The type of of ConfigurationSection</typeparam>
/// <param name="config">The config instance</param>
/// <param name="action">An action to customize the configuration values.</param>
/// <returns>The configure instance</returns>
public static Configure OverrideConfigSection<T>(this Configure config, Action<IAllowOverriding<T>> action)
where T : ConfigurationSection, new()
{
var settings = new OverrideSettings<T>(Configure.ConfigurationSource ?? new DefaultConfigurationSource());
action(settings);
config.CustomConfigurationSource(((IProvideConfigurationSource)settings).Create());
return config;
}
/// <summary>
/// Wraps the current configuration source with an outer configuration source. If the outer
/// source returns a null value, then the wrapper will delegate to calling the innter source.
/// If the current config source is null, then it will instantiate a new DefaultConfigurationSource
/// so make sure to call config.CustomConfigurationSource first if you don't want the default configuration
/// source being used.
/// </summary>
/// <param name="config">The configure instance</param>
/// <param name="outer">The IConfigurationSource to wrap the current source with.</param>
/// <returns>The current configuration instance.</returns>
public static Configure WrapConfigurationSource(this Configure config, IConfigurationSource outer)
{
config.CustomConfigurationSource(
new WrappingConfigurationSource(Configure.ConfigurationSource ?? new DefaultConfigurationSource(), outer));
return config;
}
}
}
namespace NServiceBus.Override
{
using System;
using System.Configuration;
using global::NServiceBus.Config.ConfigurationSource;
public interface IProvideConfigurationSource
{
IConfigurationSource Create();
}
public interface IAllowOverriding<out T>
{
void Override(Action<T> action);
}
class OverrideSettings<T> : IProvideConfigurationSource, IAllowOverriding<T>
where T : ConfigurationSection, new()
{
readonly IConfigurationSource _innerSource;
T _current;
public OverrideSettings(IConfigurationSource innerSource)
{
_innerSource = innerSource ?? new NullConfigurationSource();
}
public void Override(Action<T> action)
{
_current = _current ?? _innerSource.GetConfiguration<T>() ?? new T();
action(_current);
}
IConfigurationSource IProvideConfigurationSource.Create()
{
return new OverrideConfigurationSource(_innerSource, _current);
}
}
class WrappingConfigurationSource : IConfigurationSource
{
readonly IConfigurationSource _inner;
readonly IConfigurationSource _current;
public WrappingConfigurationSource(IConfigurationSource inner, IConfigurationSource current)
{
_inner = inner;
_current = current;
}
public T GetConfiguration<T>() where T : class, new()
{
return _current.GetConfiguration<T>() ?? _inner.GetConfiguration<T>();
}
}
class OverrideConfigurationSource : IConfigurationSource
{
readonly IConfigurationSource _innerSource;
readonly ConfigurationSection _overrideSection;
public OverrideConfigurationSource(IConfigurationSource innerSource, ConfigurationSection overrideSection)
{
if (overrideSection == null)
{
throw new ArgumentNullException("overrideSection");
}
_innerSource = innerSource ?? new NullConfigurationSource();
_overrideSection = overrideSection;
}
public T GetConfiguration<T>() where T : class, new()
{
if (typeof(T).Equals(_overrideSection.GetType()))
return _overrideSection as T;
return _innerSource.GetConfiguration<T>();
}
}
class NullConfigurationSource : IConfigurationSource
{
public T GetConfiguration<T>() where T : class, new()
{
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment