Skip to content

Instantly share code, notes, and snippets.

@sheastrickland
Created February 16, 2015 00:33
Show Gist options
  • Save sheastrickland/03f8850e156ae28102d6 to your computer and use it in GitHub Desktop.
Save sheastrickland/03f8850e156ae28102d6 to your computer and use it in GitHub Desktop.
ConfigInjector, support Autofac.Module settings and bootstrapping into IContainer
using System;
using Autofac;
namespace Syringe
{
/// <summary>
/// Bootstrapper, which obtains the dynamic CloudModule setting and loads the module into the Autofac Container.
/// </summary>
/// <remarks>
/// This required IBootstrapPostContainer, as it required access to the IContainer instance. IStartable runs before the instance is available.
/// </remarks>
internal class CloudModuleBootstrapper : IoC.IBootstrapPostContainer
{
public CloudModuleBootstrapper(CloudModuleSetting cloudModuleSetting, Func<IContainer> containerAccessor)
{
var updater = new ContainerBuilder();
updater.RegisterModule(cloudModuleSetting.Value);
updater.Update(containerAccessor());
}
}
}
using Autofac;
using ConfigInjector;
namespace Syringe
{
/// <summary>
/// The setting for the Autofac Cloud module to load at startup. e.g. Syringe.AmazonModule
/// </summary>
public class CloudModuleSetting : ConfigurationSetting<Module>
{
}
}
using Autofac;
using ConfigInjector.Configuration;
namespace Syringe
{
/// <summary>
/// This Autofac module groups registrations related to the ConfigInjector reading AppSettings.
/// </summary>
public class ConfigurationModule : Module
{
protected override void Load(ContainerBuilder builder)
{
ConfigurationConfigurator
.RegisterConfigurationSettings()
.FromAssemblies(ThisAssembly)
.RegisterWithContainer(configSetting => builder.RegisterInstance(configSetting)
.AsSelf()
.SingleInstance())
.WithCustomValueParsers(new TypeValueParser<Module>())
.WithSettingKeyConventions(new LegacySettingKeyConvention())
.AllowConfigurationEntriesThatDoNotHaveSettingsClasses(true)
.DoYourThing();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Autofac;
namespace Syringe
{
public static class IoC
{
/// <summary>
/// Required IBootstrapPostContainer convention, as we required access to the IContainer instance, and IStartable runs before the instance is available.
/// </summary>>
internal interface IBootstrapPostContainer
{
}
public static void Startup(params Assembly[] moduleAssembliesToScan)
{
var builder = new ContainerBuilder();
//make container available for special circumstances
builder.RegisterInstance((Func<IContainer>)(() => Container));
//scan these assemblies, looking for Autofac.Module implementations. These are ways of grouping like registrations.
var assemblies = new[] { typeof(IoC).Assembly }.Concat(moduleAssembliesToScan).ToArray();
builder.RegisterAssemblyModules(assemblies);
builder.RegisterAssemblyTypes(assemblies)
.AssignableTo<IBootstrapPostContainer>()
.AsImplementedInterfaces()
.SingleInstance();
Container = builder.Build();
//Once the container instance is available, perform one-off bootstrapping.
Container.Resolve<IEnumerable<IBootstrapPostContainer>>();
}
public static void Shutdown()
{
try
{
if (Container != null) Container.Dispose();
}
catch (ObjectDisposedException)
{
}
}
public static IContainer Container { get; private set; }
}
}
using System;
using ConfigInjector.ValueParsers;
namespace Syringe
{
/// <summary>
/// Extending the ConfigInjector value parser's to support custom types.
/// </summary>
/// <remarks>
/// <see cref="T"/> must have parameterless constructor
/// </remarks>
/// <typeparam name="T">The closed ConfigurationSetting type to parse</typeparam>
internal class TypeValueParser<T> : IValueParser
{
public int SortOrder
{
get { return int.MaxValue - 2; }
}
public bool CanParse(Type settingValueType)
{
return typeof(T).IsAssignableFrom(settingValueType);
}
public object Parse(Type settingValueType, string settingValueString)
{
var type = Type.GetType(settingValueString, true);
if (!typeof (T).IsAssignableFrom(type))
throw new Exception(string.Format("Value is not of type {0}", typeof (T)));
return Activator.CreateInstance(type);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment