Last active
February 19, 2018 18:40
-
-
Save AtomicBlom/722b0d264d4545464d66d6f3d92042b4 to your computer and use it in GitHub Desktop.
Template10AutofacIntegration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 */ } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This will be very easy to migrate to the updated Template10.2