2019-08-19 16:36:26 +02:00
|
|
|
|
using System;
|
2022-11-23 09:13:38 +01:00
|
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2019-08-19 16:36:26 +02:00
|
|
|
|
using Autofac;
|
|
|
|
|
using Autofac.Builder;
|
|
|
|
|
|
2022-11-22 13:20:47 +01:00
|
|
|
|
// ReSharper disable UnusedMember.Global
|
|
|
|
|
|
2019-08-19 16:36:26 +02:00
|
|
|
|
namespace Tapeti.Autofac
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 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.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class AutofacDependencyResolver : IDependencyContainer
|
|
|
|
|
{
|
2022-11-23 09:13:38 +01:00
|
|
|
|
private ContainerBuilder? containerBuilder;
|
|
|
|
|
private IContainer? container;
|
2019-08-19 16:36:26 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2022-11-23 09:13:38 +01:00
|
|
|
|
/// The built container. Either set directly, or use the Build method to build the
|
2019-08-19 16:36:26 +02:00
|
|
|
|
/// update this reference.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public IContainer Container
|
|
|
|
|
{
|
2022-11-23 09:13:38 +01:00
|
|
|
|
get => container ?? throw new ArgumentNullException(nameof(container));
|
2019-08-19 16:36:26 +02:00
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
container = value;
|
2022-11-23 09:13:38 +01:00
|
|
|
|
containerBuilder = null;
|
2019-08-19 16:36:26 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-05-29 21:51:58 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// </summary>
|
2019-08-19 16:36:26 +02:00
|
|
|
|
public AutofacDependencyResolver(ContainerBuilder containerBuilder)
|
|
|
|
|
{
|
|
|
|
|
this.containerBuilder = containerBuilder;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Builds the container, updates the Container property and returns the newly built IContainer.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public IContainer Build(ContainerBuildOptions options = ContainerBuildOptions.None)
|
|
|
|
|
{
|
|
|
|
|
CheckContainerBuilder();
|
|
|
|
|
Container = containerBuilder.Build(options);
|
|
|
|
|
|
2022-11-23 09:13:38 +01:00
|
|
|
|
return Container;
|
2019-08-19 16:36:26 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public T Resolve<T>() where T : class
|
|
|
|
|
{
|
|
|
|
|
CheckContainer();
|
|
|
|
|
return Container.Resolve<T>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public object Resolve(Type type)
|
|
|
|
|
{
|
|
|
|
|
CheckContainer();
|
|
|
|
|
return Container.Resolve(type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public void RegisterDefault<TService, TImplementation>() where TService : class where TImplementation : class, TService
|
|
|
|
|
{
|
|
|
|
|
CheckContainerBuilder();
|
|
|
|
|
containerBuilder
|
|
|
|
|
.RegisterType<TImplementation>()
|
|
|
|
|
.As<TService>()
|
|
|
|
|
.PreserveExistingDefaults();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public void RegisterDefault<TService>(Func<TService> factory) where TService : class
|
|
|
|
|
{
|
|
|
|
|
CheckContainerBuilder();
|
|
|
|
|
containerBuilder
|
2022-11-22 13:20:47 +01:00
|
|
|
|
.Register(_ => factory())
|
2019-08-19 16:36:26 +02:00
|
|
|
|
.As<TService>()
|
|
|
|
|
.PreserveExistingDefaults();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public void RegisterDefaultSingleton<TService, TImplementation>() where TService : class where TImplementation : class, TService
|
|
|
|
|
{
|
|
|
|
|
CheckContainerBuilder();
|
|
|
|
|
containerBuilder
|
|
|
|
|
.RegisterType<TImplementation>()
|
|
|
|
|
.As<TService>()
|
|
|
|
|
.SingleInstance()
|
|
|
|
|
.PreserveExistingDefaults();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public void RegisterDefaultSingleton<TService>(TService instance) where TService : class
|
|
|
|
|
{
|
|
|
|
|
CheckContainerBuilder();
|
|
|
|
|
containerBuilder
|
|
|
|
|
.RegisterInstance(instance)
|
|
|
|
|
.As<TService>()
|
|
|
|
|
.SingleInstance()
|
|
|
|
|
.PreserveExistingDefaults();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public void RegisterDefaultSingleton<TService>(Func<TService> factory) where TService : class
|
|
|
|
|
{
|
|
|
|
|
CheckContainerBuilder();
|
|
|
|
|
containerBuilder
|
2022-11-22 13:20:47 +01:00
|
|
|
|
.Register(_ => factory())
|
2019-08-19 16:36:26 +02:00
|
|
|
|
.As<TService>()
|
|
|
|
|
.SingleInstance()
|
|
|
|
|
.PreserveExistingDefaults();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-11-23 09:13:38 +01:00
|
|
|
|
[MemberNotNull(nameof(containerBuilder))]
|
2019-08-19 16:36:26 +02:00
|
|
|
|
private void CheckContainerBuilder()
|
|
|
|
|
{
|
|
|
|
|
if (containerBuilder == null)
|
|
|
|
|
throw new InvalidOperationException("Container property has already been set on AutofacDependencyResolver");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|