using System;
using Autofac;
using Autofac.Builder;
namespace Tapeti.Autofac
{
///
///
/// Dependency resolver and container implementation for Autofac.
/// Since this class needs access to both the ContainerBuilder and the built IContainer,
/// either let AutofacDependencyResolver build the container by calling it's Build method,
/// or set the Container property manually.
///
public class AutofacDependencyResolver : IDependencyContainer
{
private ContainerBuilder containerBuilder;
private IContainer container;
///
/// The built container. Either set directly, or use the Build method to built the
/// update this reference.
///
public IContainer Container
{
get => container;
set
{
container = value;
if (value != null)
containerBuilder = null;
}
}
///
///
public AutofacDependencyResolver(ContainerBuilder containerBuilder)
{
this.containerBuilder = containerBuilder;
}
///
/// Builds the container, updates the Container property and returns the newly built IContainer.
///
public IContainer Build(ContainerBuildOptions options = ContainerBuildOptions.None)
{
CheckContainerBuilder();
Container = containerBuilder.Build(options);
return container;
}
///
public T Resolve() where T : class
{
CheckContainer();
return Container.Resolve();
}
///
public object Resolve(Type type)
{
CheckContainer();
return Container.Resolve(type);
}
///
public void RegisterDefault() where TService : class where TImplementation : class, TService
{
CheckContainerBuilder();
containerBuilder
.RegisterType()
.As()
.PreserveExistingDefaults();
}
///
public void RegisterDefault(Func factory) where TService : class
{
CheckContainerBuilder();
containerBuilder
.Register(context => factory())
.As()
.PreserveExistingDefaults();
}
///
public void RegisterDefaultSingleton() where TService : class where TImplementation : class, TService
{
CheckContainerBuilder();
containerBuilder
.RegisterType()
.As()
.SingleInstance()
.PreserveExistingDefaults();
}
///
public void RegisterDefaultSingleton(TService instance) where TService : class
{
CheckContainerBuilder();
containerBuilder
.RegisterInstance(instance)
.As()
.SingleInstance()
.PreserveExistingDefaults();
}
///
public void RegisterDefaultSingleton(Func factory) where TService : class
{
CheckContainerBuilder();
containerBuilder
.Register(context => factory())
.As()
.SingleInstance()
.PreserveExistingDefaults();
}
///
public void RegisterController(Type type)
{
CheckContainerBuilder();
containerBuilder
.RegisterType(type)
.AsSelf();
}
private void CheckContainer()
{
if (container == null)
throw new InvalidOperationException("Container property has not been set yet on AutofacDependencyResolver");
}
private void CheckContainerBuilder()
{
if (containerBuilder == null)
throw new InvalidOperationException("Container property has already been set on AutofacDependencyResolver");
}
}
}