Skip to content

Instantly share code, notes, and snippets.

@AtomicBlom
Last active February 19, 2018 18:40
Show Gist options
  • Save AtomicBlom/722b0d264d4545464d66d6f3d92042b4 to your computer and use it in GitHub Desktop.
Save AtomicBlom/722b0d264d4545464d66d6f3d92042b4 to your computer and use it in GitHub Desktop.
Template10AutofacIntegration
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Autofac;
using Template10.Services.Dependency;
namespace Sample.Framework.Dependency.Autofac
{
//Current implementation of Template10 assumes that registrations can be added ad-hoc.
//Working around this by creating lifetime scopes to add registrations as needed.
//Template10 seems to assume that all services are singleton as there is no obvious way to
//determine the intention and no caching of services is done inside Template10.
public class AutofacContainerAdapter : IContainerAdapter
{
public AutofacContainerAdapter()
{
_currentBuilder = new ContainerBuilder();
}
private readonly object _lock = new object();
private ContainerBuilder _currentBuilder;
private ILifetimeScope _currentContainer;
public ILifetimeScope Container => _currentContainer;
public ContainerBuilder ContainerBuilder => _currentBuilder;
private readonly List<Action<ContainerBuilder>> _actionsToPerform = new List<Action<ContainerBuilder>>();
public TInterface Resolve<TInterface>() where TInterface : class
{
VerifyContainerBuilt();
return _currentContainer.Resolve<TInterface>();
}
public TInterface Resolve<TInterface>(string key) where TInterface : class
{
VerifyContainerBuilt();
return _currentContainer.ResolveNamed<TInterface>(key);
}
public void Register<TInterface, TClass>() where TInterface : class where TClass : class, TInterface
{
_actionsToPerform.Add(containerBuilder =>
_currentBuilder.RegisterType<TClass>().As<TInterface>().SingleInstance().PreserveExistingDefaults()
);
}
public void Register<TInterface, TClass>(string key) where TInterface : class where TClass : class, TInterface
{
_actionsToPerform.Add(containerBuilder =>
containerBuilder.RegisterType<TClass>().As<TInterface>().Named<TInterface>(key).SingleInstance().PreserveExistingDefaults()
);
}
public void RegisterInstance<TClass>(TClass instance) where TClass : class
{
_actionsToPerform.Add(containerBuilder =>
containerBuilder.Register(ctx => instance).SingleInstance().SingleInstance().PreserveExistingDefaults()
);
}
public void RegisterInstance<TInterface, TClass>(TClass instance) where TInterface : class where TClass : class, TInterface
{
_actionsToPerform.Add(containerBuilder =>
_currentBuilder.Register(ctx => instance).As<TInterface>().SingleInstance().PreserveExistingDefaults()
);
}
[DebuggerStepThrough]
private void VerifyContainerBuilt()
{
lock (_lock)
{
if (_currentContainer == null)
{
ApplyActions(_currentBuilder);
_currentContainer = _currentBuilder.Build();
_currentBuilder = null;
}
if (_actionsToPerform.Any())
{
_currentContainer = _currentContainer?.BeginLifetimeScope(ApplyActions);
}
}
}
[DebuggerStepThrough]
private void ApplyActions(ContainerBuilder containerBuilder)
{
foreach (var action in _actionsToPerform)
{
action(containerBuilder);
}
_actionsToPerform.Clear();
}
}
}
using Autofac;
using Template10.Services.Dependency;
namespace Sample.Framework.Dependency.Autofac
{
public class AutofacDependencyService : DependencyService, IDependencyService2<IContainer>
{
public AutofacDependencyService() : base(new AutofacContainerAdapter())
{
}
IContainer IDependencyService2<IContainer>.Container => ((AutofacContainerAdapter)Adapter).Container;
public ContainerBuilder ContainerBuilder => ((AutofacContainerAdapter)Adapter).ContainerBuilder;
}
}
using System;
using Autofac;
using Sample.Framework.Dependency.Autofac;
using Template10.BootStrap;
using Template10.Services.Dependency;
namespace Sample.Framework.Bootstrap.Autofac
{
public abstract class BootStrapper
: BootStrapperBase
{
public sealed override IDependencyService CreateDependecyService()
{
return new AutofacDependencyService();
}
public sealed override void RegisterCustomDependencies(IDependencyService dependencyService)
{
if (dependencyService is AutofacDependencyService autofacDependencyService)
{
SetupAutofac(autofacDependencyService.ContainerBuilder);
return;
}
throw new NotImplementedException("This boostrapper explicitly depends on AutoFac to allow scoping");
}
protected virtual void SetupAutofac(ContainerBuilder container) { /* empty */ }
}
}
@JerryNixon
Copy link

This will be very easy to migrate to the updated Template10.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment