#if !PUREDI_API_SUPPRESSION || PUREDI_API_V2
#pragma warning disable
#if !PUREDI_API_FUNC_SUPPRESSION
namespace
System
{
#if NET20
internal
delegate
TResult Func<
out
TResult>();
#endif
#if NET20 || NET35
internal
delegate
TResult Func<
in
T,
out
TResult>(T arg);
internal
delegate
TResult Func<
in
T1,
in
T2,
out
TResult>(T1 arg1, T2 arg2);
internal
delegate
TResult Func<
in
T1,
in
T2,
in
T3,
out
TResult>(T1 arg1, T2 arg2, T3 arg3);
internal
delegate
TResult Func<
in
T1,
in
T2,
in
T3,
in
T4,
out
TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
internal
delegate
TResult Func<
in
T1,
in
T2,
in
T3,
in
T4,
in
T5,
out
TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
internal
delegate
TResult Func<
in
T1,
in
T2,
in
T3,
in
T4,
in
T5,
in
T6,
out
TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
internal
delegate
TResult Func<
in
T1,
in
T2,
in
T3,
in
T4,
in
T5,
in
T6,
in
T7,
out
TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
internal
delegate
TResult Func<
in
T1,
in
T2,
in
T3,
in
T4,
in
T5,
in
T6,
in
T7,
in
T8,
out
TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
#endif
}
#endif
namespace
Pure.DI
{
using
System;
/// <summary>
/// Binding lifetimes.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IDependency>().As(Lifetime.Singleton).To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="Pure.DI.DI.Setup"/>
/// <seealso cref="IBinding.As"/>
/// <seealso cref="IConfiguration.DefaultLifetime"/>
internal
enum
Lifetime
{
/// <summary>
/// Specifies to create a new dependency instance each time. This is the default value and can be omitted.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IDependency>().As(Lifetime.Transient).To<Dependency>();
/// </code>
/// This is the default lifetime, it can be omitted, for example:
/// <code>
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
Transient,
/// <summary>
/// Ensures that there will be a single instance of the dependency for each composition.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IDependency>().As(Lifetime.Singleton).To<Dependency>();
/// </code>
/// </example>
/// </summary>
Singleton,
/// <summary>
/// Guarantees that there will be a single instance of the dependency for each root of the composition.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IDependency>().As(Lifetime.PerResolve).To<Dependency>();
/// </code>
/// </example>
/// </summary>
PerResolve,
/// <summary>
/// Does not guarantee that there will be a single instance of the dependency for each root of the composition, but is useful to reduce the number of instances of type.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IDependency>().As(Lifetime.PerBlock).To<Dependency>();
/// </code>
/// </example>
/// </summary>
PerBlock,
/// <summary>
/// Ensures that there will be a single instance of the dependency for each scope.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IDependency>().As(Lifetime.Singleton).To<Dependency>();
/// </code>
/// </example>
/// </summary>
Scoped
}
/// <summary>
/// Hints for the code generator and can be used to fine tune code generation.
/// <example>
/// <code>
/// // Resolve = Off
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.Resolve, "Off")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
internal
enum
Hint
{
/// <summary>
/// <c>On</c> or <c>Off</c>. Determines whether to generate <c>Resolve</c> methods. <c>On</c> by default.
/// <example>
/// <code>
/// // Resolve = Off
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.Resolve, "Off")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
Resolve,
/// <summary>
/// <c>On</c> or <c>Off</c>. Determines whether to use partial <c>OnNewInstance</c> method. <c>Off</c> by default.
/// <example>
/// <code>
/// // OnNewInstance = On
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnNewInstance, "On")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnNewInstance,
/// <summary>
/// <c>On</c> or <c>Off</c>. Determines whether to generate partial <c>OnNewInstance</c> method when the _OnNewInstance_ hint is <c>On</c>. <c>On</c> by default.
/// <example>
/// <code>
/// // OnNewInstancePartial = On
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnNewInstancePartial, "On")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnNewInstancePartial,
/// <summary>
/// The regular expression to filter OnNewInstance by the instance type name. ".+" by default.
/// <example>
/// <code>
/// // OnNewInstanceImplementationTypeNameRegularExpression = Dependency
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnNewInstanceImplementationTypeNameRegularExpression, "Dependency")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnNewInstanceImplementationTypeNameRegularExpression,
/// <summary>
/// The regular expression to filter OnNewInstance by the tag. ".+" by default.
/// <example>
/// <code>
/// // OnNewInstanceTagRegularExpression = IDependency
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnNewInstanceTagRegularExpression, "IDependency")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnNewInstanceTagRegularExpression,
/// <summary>
/// The regular expression to filter OnNewInstance by the lifetime. ".+" by default.
/// <example>
/// <code>
/// // OnNewInstanceLifetimeRegularExpression = Singleton
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnNewInstanceLifetimeRegularExpression, "Singleton")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnNewInstanceLifetimeRegularExpression,
/// <summary>
/// <c>On</c> or <c>Off</c>. Determines whether to use partial <c>OnDependencyInjection</c> method to control of dependency injection. <c>Off</c> by default.
/// <example>
/// <code>
/// // OnDependencyInjection = On
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnDependencyInjection, "On")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnDependencyInjection,
/// <summary>
/// <c>On</c> or <c>Off</c>. Determines whether to generate partial <c>OnDependencyInjection</c> method when the _OnDependencyInjection_ hint is <c>On</c> to control of dependency injection. <c>On</c> by default.
/// <example>
/// <code>
/// // OnDependencyInjectionPartial = On
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnDependencyInjectionPartial, "On")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnDependencyInjectionPartial,
/// <summary>
/// The regular expression to filter OnDependencyInjection by the instance type name. ".+" by default.
/// <example>
/// <code>
/// // OnDependencyInjectionImplementationTypeNameRegularExpression = Dependency
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnDependencyInjectionImplementationTypeNameRegularExpression, "Dependency")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnDependencyInjectionImplementationTypeNameRegularExpression,
/// <summary>
/// The regular expression to filter OnDependencyInjection by the resolving type name. ".+" by default.
/// <example>
/// <code>
/// // OnDependencyInjectionContractTypeNameRegularExpression = IDependency
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnDependencyInjectionContractTypeNameRegularExpression, "IDependency")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnDependencyInjectionContractTypeNameRegularExpression,
/// <summary>
/// The regular expression to filter OnDependencyInjection by the tag. ".+" by default.
/// <example>
/// <code>
/// // OnDependencyInjectionTagRegularExpression = MyTag
/// DI.Setup("Composition")
/// .Bind<IDependency>("MyTag").To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnDependencyInjectionTagRegularExpression, "MyTag")
/// .Bind<IDependency>("MyTag").To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnDependencyInjectionTagRegularExpression,
/// <summary>
/// The regular expression to filter OnDependencyInjection by the lifetime. ".+" by default.
/// <example>
/// <code>
/// // OnDependencyInjectionLifetimeRegularExpression = Singleton
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnDependencyInjectionLifetimeRegularExpression, "Singleton")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnDependencyInjectionLifetimeRegularExpression,
/// <summary>
/// <c>On</c> or <c>Off</c>. Determines whether to use a partial <c>OnCannotResolve<T>(...)</c> method to handle a scenario in which the dependency cannot be resolved. <c>Off</c> by default.
/// <example>
/// <code>
/// // OnCannotResolve = On
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnCannotResolve, "On")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnCannotResolve,
/// <summary>
/// <c>On</c> or <c>Off</c>. Determines whether to generate a partial <c>OnCannotResolve<T>(...)</c> method when the <c>OnCannotResolve</c> hint is <c>On</c> to handle a scenario in which the dependency cannot be resolved. <c>On</c> by default.
/// <example>
/// <code>
/// // OnCannotResolvePartial = On
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnCannotResolvePartial, "On")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnCannotResolvePartial,
/// <summary>
/// The regular expression to filter OnCannotResolve by the resolving type name. ".+" by default.
/// <example>
/// <code>
/// // OnCannotResolveContractTypeNameRegularExpression = OtherType
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnCannotResolveContractTypeNameRegularExpression, "OtherType")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnCannotResolveContractTypeNameRegularExpression,
/// <summary>
/// The regular expression to filter OnCannotResolve by the tag. ".+" by default.
/// <example>
/// <code>
/// // OnCannotResolveTagRegularExpression = MyTag
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnCannotResolveTagRegularExpression, "MyTag")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnCannotResolveTagRegularExpression,
/// <summary>
/// The regular expression to filter OnCannotResolve by the lifetime. ".+" by default.
/// <example>
/// <code>
/// // OnCannotResolveLifetimeRegularExpression = Singleton
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnCannotResolveLifetimeRegularExpression, "Singleton")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnCannotResolveLifetimeRegularExpression,
/// <summary>
/// <c>On</c> or <c>Off</c>. Determines whether to use a static partial <c>OnNewRoot<T>(...)</c> method to handle the new Composition root registration event. <c>Off</c> by default.
/// <example>
/// <code>
/// // OnNewRoot = On
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnNewRoot, "On")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnNewRoot,
/// <summary>
/// <c>On</c> or <c>Off</c>. Determines whether to generate a static partial <c>OnNewRoot<T>(...)</c> method when the <c>OnNewRoot</c> hint is <c>On</c> to handle the new Composition root registration event. <c>On</c> by default.
/// <example>
/// <code>
/// // OnNewRootPartial = On
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.OnNewRootPartial, "On")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
OnNewRootPartial,
/// <summary>
/// <c>On</c> or <c>Off</c>. Determine if the <c>ToString()</c> method should be generated. This method provides a text-based class diagram in the format mermaid. <c>Off</c> by default.
/// <example>
/// <code>
/// // ToString = On
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.ToString, "On")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
ToString,
/// <summary>
/// <c>On</c> or <c>Off</c>. This hint determines whether object Composition will be created in a thread-safe manner. <c>On</c> by default.
/// <example>
/// <code>
/// // ThreadSafe = Off
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.ThreadSafe, "Off")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
ThreadSafe,
/// <summary>
/// Overrides modifiers of the method <c>public T Resolve<T>()</c>. "public" by default.
/// <example>
/// <code>
/// // ResolveMethodModifiers = internal
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.ResolveMethodModifiers, "internal")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
ResolveMethodModifiers,
/// <summary>
/// Overrides name of the method <c>public T Resolve<T>()</c>. "Resolve" by default.
/// <example>
/// <code>
/// // ResolveMethodName = GetService
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.ResolveMethodName, "GetService")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
ResolveMethodName,
/// <summary>
/// Overrides modifiers of the method <c>public T Resolve<T>(object? tag)</c>. "public" by default.
/// <example>
/// <code>
/// // ResolveByTagMethodModifiers = internal
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.ResolveByTagMethodModifiers, "internal")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
ResolveByTagMethodModifiers,
/// <summary>
/// Overrides name of the method <c>public T Resolve<T>(object? tag)</c>. "Resolve" by default.
/// <example>
/// For example:
/// <code>
/// // ResolveByTagMethodName = GetService
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.ResolveByTagMethodName, "GetService")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
ResolveByTagMethodName,
/// <summary>
/// Overrides modifiers of the method <c>public object Resolve(Type type)</c>. "public" by default.
/// <example>
/// <code>
/// // ObjectResolveMethodModifiers = internal
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.ObjectResolveMethodModifiers, "internal")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
ObjectResolveMethodModifiers,
/// <summary>
/// Overrides name of the method <c>public object Resolve(Type type)</c>. "Resolve" by default.
/// <example>
/// <code>
/// // ObjectResolveMethodName = GetService
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.ObjectResolveMethodName, "GetService")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
ObjectResolveMethodName,
/// <summary>
/// Overrides modifiers of the method <c>public object Resolve(Type type, object? tag)</c>. "public" by default.
/// <example>
/// <code>
/// // ObjectResolveByTagMethodModifiers = internal
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.ObjectResolveByTagMethodModifiers, "internal")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
ObjectResolveByTagMethodModifiers,
/// <summary>
/// Overrides name of the method <c>public object Resolve(Type type, object? tag)</c>. "Resolve" by default.
/// <example>
/// <code>
/// // ObjectResolveByTagMethodName = GetService
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.ObjectResolveByTagMethodName, "GetService")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
ObjectResolveByTagMethodName,
/// <summary>
/// Overrides modifiers of the method <c>public void Dispose()</c>. "public" by default.
/// <example>
/// <code>
/// // DisposeMethodModifiers = internal
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.DisposeMethodModifiers, "internal")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
DisposeMethodModifiers,
/// <summary>
/// Overrides modifiers of the method <c>public <see cref="ValueTask"/> DisposeAsyncMethodModifiers()</c>. "public" by default.
/// <example>
/// <code>
/// // DisposeAsyncMethodModifiers = internal
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.DisposeAsyncMethodModifiers, "internal")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
DisposeAsyncMethodModifiers,
/// <summary>
/// <c>On</c> or <c>Off</c>. Specifies whether the generated code should be formatted. This option consumes a lot of CPU resources. <c>Off</c> by default.
/// <example>
/// <code>
/// // FormatCode = On
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.FormatCode, "On")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
FormatCode,
/// <summary>
/// <c>Error</c> or <c>Warning</c> or <c>Info</c> or <c>Hidden</c>. Indicates the severity level of the situation when, in the binding, an implementation does not implement a contract. <c>Error</c> by default.
/// <example>
/// <code>
/// // FormatCode = On
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.SeverityOfNotImplementedContracts, "On")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
SeverityOfNotImplementedContract,
/// <summary>
/// <c>On</c> or <c>Off</c>. Specifies whether the generated code should be commented. <c>On</c> by default.
/// <example>
/// <code>
/// // Comments = Off
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// <br/>
/// or using the API call <see cref="IConfiguration.Hint"/>:
/// <code>
/// DI.Setup("Composition")
/// .Hint(Hint.Comments, "Off")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Hint"/>
Comments
}
/// <summary>
/// Represents a generic type argument attribute. It allows you to create custom generic type argument such as <see cref="TTS"/>, <see cref="TTDictionary{TKey,TValue}"/>, etc.
/// <example>
/// <code>
/// [GenericTypeArgument]
/// internal interface TTMy: IMy { }
/// </code>
/// </example>
/// </summary>
[global::System.AttributeUsage(global::System.AttributeTargets.Class | global::System.AttributeTargets.Interface | global::System.AttributeTargets.Struct | global::System.AttributeTargets.Enum)]
#if !NET20 && !NET35 && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && !NETCOREAPP1_0 && !NETCOREAPP1_1
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
internal
sealed
class
GenericTypeArgumentAttribute : global::System.Attribute { }
/// <summary>
/// Represents an ordinal attribute.
/// This attribute is part of the API, but you can use your own attribute at any time, and this allows you to define them in the assembly and namespace you want.
/// <example>
/// For constructors, it defines the sequence of attempts to use a particular constructor to create an object:
/// <code>
/// class Service : IService
/// {
/// private readonly string _name;
///
///
/// [Ordinal(1)]
/// public Service(IDependency dependency) =>
/// _name = "with dependency";
///
///
/// [Ordinal(0)]
/// public Service(string name) => _name = name;
/// }
/// </code>
/// <br/>
/// For fields, properties and methods, it specifies to perform dependency injection and defines the sequence:
/// <code>
/// class Person : IPerson
/// {
/// private readonly string _name = "";
///
/// [Ordinal(0)]
/// public int Id;
///
///
/// [Ordinal(1)]
/// public string FirstName
/// {
/// set
/// {
/// _name = value;
/// }
/// }
///
///
/// public IDependency? Dependency { get; private set; }
///
///
/// [Ordinal(2)]
/// public void SetDependency(IDependency dependency) =>
/// Dependency = dependency;
/// }
/// </code>
/// </example>
/// </summary>
/// <seealso cref="TagAttribute"/>
/// <seealso cref="TypeAttribute"/>
[global::System.AttributeUsage(global::System.AttributeTargets.Constructor | global::System.AttributeTargets.Method | global::System.AttributeTargets.Property | global::System.AttributeTargets.Field, AllowMultiple =
false
)]
#if !NET20 && !NET35 && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && !NETCOREAPP1_0 && !NETCOREAPP1_1
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
internal
class
OrdinalAttribute : global::System.Attribute
{
/// <summary>
/// Creates an attribute instance.
/// </summary>
/// <param name="ordinal">The injection ordinal.</param>
public
OrdinalAttribute(
int
ordinal) { }
}
/// <summary>
/// Represents a tag attribute overriding an injection tag. The tag can be a constant, a type, or a value of an enumerated type.
/// This attribute is part of the API, but you can use your own attribute at any time, and this allows you to define them in the assembly and namespace you want.
/// <example>
/// Sometimes it's important to take control of building a dependency graph. For example, when there are multiple implementations of the same contract. In this case, tags will help:
/// <code>
/// interface IDependency { }
///
///
/// class AbcDependency : IDependency { }
///
///
/// class XyzDependency : IDependency { }
///
///
/// class Dependency : IDependency { }
///
///
/// interface IService
/// {
/// IDependency Dependency1 { get; }
///
///
/// IDependency Dependency2 { get; }
/// }
///
///
/// class Service : IService
/// {
/// public Service(
/// [Tag("Abc")] IDependency dependency1,
/// [Tag("Xyz")] IDependency dependency2)
/// {
/// Dependency1 = dependency1;
/// Dependency2 = dependency2;
/// }
///
/// public IDependency Dependency1 { get; }
///
///
/// public IDependency Dependency2 { get; }
/// }
///
///
/// DI.Setup("Composition")
/// .Bind<IDependency>("Abc").To<AbcDependency>()
/// .Bind<IDependency>("Xyz").To<XyzDependency>()
/// .Bind<IService>().To<Service>().Root<IService>("Root");
/// </code>
/// </example>
/// </summary>
/// <seealso cref="OrdinalAttribute"/>
/// <seealso cref="TypeAttribute"/>
[global::System.AttributeUsage(global::System.AttributeTargets.Parameter | global::System.AttributeTargets.Property | global::System.AttributeTargets.Field, AllowMultiple =
false
)]
#if !NET20 && !NET35 && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && !NETCOREAPP1_0 && !NETCOREAPP1_1
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
internal
class
TagAttribute : global::System.Attribute
{
/// <summary>
/// Creates an attribute instance.
/// </summary>
/// <param name="tag">The injection tag. See also <see cref="IBinding.Tags"/></param>.
public
TagAttribute(
object
tag) { }
}
/// <summary>
/// The injection type can be defined manually using the <c>Type</c> attribute.This attribute explicitly overrides an injected type, otherwise it would be determined automatically based on the type of the constructor/method, property, or field parameter.
/// This attribute is part of the API, but you can use your own attribute at any time, and this allows you to define them in the assembly and namespace you want.
/// <example>
/// <code>
/// interface IDependency { }
///
///
/// class AbcDependency : IDependency { }
///
///
/// class XyzDependency : IDependency { }
///
///
/// interface IService
/// {
/// IDependency Dependency1 { get; }
///
/// IDependency Dependency2 { get; }
/// }
///
///
/// class Service : IService
/// {
/// public Service(
/// [Type(typeof(AbcDependency))] IDependency dependency1,
/// [Type(typeof(XyzDependency))] IDependency dependency2)
/// {
/// Dependency1 = dependency1;
/// Dependency2 = dependency2;
/// }
///
///
/// public IDependency Dependency1 { get; }
///
///
/// public IDependency Dependency2 { get; }
/// }
///
///
/// DI.Setup("Composition")
/// .Bind<IService>().To<Service>().Root<IService>("Root");
/// </code>
/// </example>
/// </summary>
/// <seealso cref="TagAttribute"/>
/// <seealso cref="OrdinalAttribute"/>
[global::System.AttributeUsage(global::System.AttributeTargets.Parameter | global::System.AttributeTargets.Property | global::System.AttributeTargets.Field, AllowMultiple =
false
)]
#if !NET20 && !NET35 && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && !NETCOREAPP1_0 && !NETCOREAPP1_1
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
internal
class
TypeAttribute : global::System.Attribute
{
/// <summary>
/// Creates an attribute instance.
/// </summary>
/// <param name="type">The injection type. See also <see cref="IConfiguration.Bind{T}"/> and <see cref="IBinding.Bind{T}"/>.</param>
public
TypeAttribute(global::System.Type type) { }
}
/// <summary>
/// Indicates that a property or method can be automatically added as a binding.
/// <example>
/// <code>
/// internal class DependencyProvider
/// {
/// [Bind()]
/// public Dependency Dep => new Dependency();
/// }
/// </code>
/// <code>
/// internal class DependencyProvider
/// {
/// [Bind(typeof(IDependency<TT>), Lifetime.Singleton)]
/// public Dependency GetDep<T>() => new Dependency();
/// }
/// </code>
/// <code>
/// internal class DependencyProvider
/// {
/// [Bind(typeof(IDependency), Lifetime.PerResolve, "some tag")]
/// public Dependency GetDep(int id) => new Dependency(id);
/// }
/// </code>
/// </example>
/// </summary>
[global::System.AttributeUsage(global::System.AttributeTargets.Property | global::System.AttributeTargets.Method | global::System.AttributeTargets.Field)]
#if !NET20 && !NET35 && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && !NETCOREAPP1_0 && !NETCOREAPP1_1
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
internal
class
BindAttribute : global::System.Attribute
{
/// <summary>
/// Creates an attribute instance.
/// </summary>
public
BindAttribute(global::System.Type type =
default
(global::System.Type), Lifetime lifetime = Lifetime.Transient,
params
object
[] tags) { }
}
/// <summary>
/// Determines how the partial class will be generated. The <see cref="DI.Setup"/> method has an additional argument <c>kind</c>, which defines the type of composition:
/// <example>
/// <code>
/// DI.Setup("BaseComposition", CompositionKind.Internal);
/// </code>
/// </example>
/// </summary>
/// <seealso cref="DI.Setup"/>
internal
enum
CompositionKind
{
/// <summary>
/// This value is used by default. If this value is specified, a normal partial class will be generated.
/// </summary>
Public,
/// <summary>
/// If this value is specified, the class will not be generated, but this setting can be used by other users as a baseline. The API call <see cref="IConfiguration.DependsOn"/> is mandatory.
/// </summary>
Internal,
/// <summary>
/// No partial classes will be created when this value is specified, but this setting is the baseline for all installations in the current project, and the API call <see cref="IConfiguration.DependsOn"/> is not required.
/// </summary>
Global
}
/// <summary>
/// Determines a kind of root of the composition.
/// </summary>
/// <seealso cref="IConfiguration.Root{T}"/>
[global::System.Flags]
internal
enum
RootKinds
{
/// <summary>
/// Specifies to use the default composition root kind.
/// </summary>
Default = RootKinds.Public | RootKinds.Property,
/// <summary>
/// Specifies to use a <c>public</c> access modifier for the root of the composition.
/// </summary>
Public = 1,
/// <summary>
/// Specifies to use a <c>internal</c> access modifier for the root of the composition.
/// </summary>
Internal = 1 << 1,
/// <summary>
/// Specifies to use a <c>private</c> access modifier for the root of the composition.
/// </summary>
Private = 1 << 2,
/// <summary>
/// Specifies to create a composition root as a property.
/// </summary>
Property = 1 << 3,
/// <summary>
/// Specifies to create a composition root as a method.
/// </summary>
Method = 1 << 4,
/// <summary>
/// Specifies to create a static root of the composition.
/// </summary>
Static = 1 << 5,
/// <summary>
/// Specifies to create a partial root of the composition.
/// </summary>
Partial = 1 << 6,
/// <summary>
/// Specifies to create a exposed root of the composition.
/// </summary>
Exposed = 1 << 7,
/// <summary>
/// Specifies to use a <c>protected</c> access modifier for the root of the composition.
/// </summary>
Protected = 1 << 8,
}
/// <summary>
/// Represents well known tags.
/// </summary>
#if !NET20 && !NET35 && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && !NETCOREAPP1_0 && !NETCOREAPP1_1
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
internal
partial
class
Tag
{
private
static
readonly
Tag Shared =
new
Tag();
/// <summary>
/// Unique tag.
/// Begins the definition of the binding.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IService>(Tag.Unique).To<Service1>()
/// .Bind<IService>(Tag.Unique).To<Service1>()
/// .Root<IEnumerable<IService>>("Root");
/// </code>
/// </example>
/// </summary>
public
static
readonly
Tag Unique = Shared;
/// <summary>
/// Tag of target implementation type.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IService>(Tag.Type).To<Service>()
/// .Root<IService>("Root", typeof(Service));
/// </code>
/// </example>
/// </summary>
public
static
readonly
Tag Type = Shared;
/// <summary>
/// This tag allows you to determine which binding will be used for explicit injection for a particular injection site.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind(Tag.On("MyNamespace.Service.Service:dep"))
/// .To<Dependency>()
/// .Bind().To<Service>()
/// .Root<IService>("Root");
/// </code>
/// </example>
/// </summary>
/// <param name="injectionSites">Set of labels for inection each, must be specified in a special format: <namespace>.<type>.<member>[:argument]. The argument is specified only for the constructor and methods. The wildcards '*' and '?' are supported. All names are case-sensitive. The global namespace prefix 'global::' must be omitted.</param>
public
static
Tag On(
params
string
[] injectionSites) => Shared;
/// <summary>
/// This tag allows you to determine which binding will be used for explicit injection for a particular constructor argument.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind(Tag.OnConstructorArg<Service>("dep"))
/// .To<Dependency>()
/// .Bind().To<Service>()
/// .Root<IService>("Root");
/// </code>
/// </example>
/// </summary>
/// <param name="argName">The name of the constructor argument.</param>
public
static
Tag OnConstructorArg<T>(
string
argName) => Shared;
/// <summary>
/// This tag allows you to define which binding will be used for explicit injection for property or field of the type.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind(Tag.OnMember<Service>("DepProperty"))
/// .To<Dependency>()
/// .Bind().To<Service>()
/// .Root<IService>("Root");
/// </code>
/// </example>
/// </summary>
/// <param name="memberName">The name of the type member.</param>
public
static
Tag OnMember<T>(
string
memberName) => Shared;
/// <summary>
/// This tag allows you to determine which binding will be used for explicit injection for a particular method argument.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind(Tag.OnMethodArg<Service>("DoSomething", "state"))
/// .To<Dependency>()
/// .Bind().To<Service>()
/// .Root<IService>("Root");
/// </code>
/// </example>
/// </summary>
/// <param name="methodName">The name of the type method.</param>
/// <param name="argName">The name of the method argument.</param>
public
static
Tag OnMethodArg<T>(
string
methodName,
string
argName) => Shared;
}
/// <summary>
/// This abstraction allows a disposable object to be disposed of.
/// </summary>
internal
interface
IOwned
: global::System.IDisposable
#if NETCOREAPP3_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
, global::System.IAsyncDisposable
#endif
{
}
/// <summary>
/// Performs accumulation and disposal of disposable objects.
/// </summary>
#if !NET20 && !NET35 && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && !NETCOREAPP1_0 && !NETCOREAPP1_1
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
internal
sealed
partial
class
Owned: global::System.Collections.Generic.List<
object
>, global::Pure.DI.IOwned
{
private
volatile
bool
_isDisposed;
/// <inheritdoc />
public
void
Dispose()
{
if
(_isDisposed)
{
return
;
}
_isDisposed =
true
;
try
{
for
(
var
i = Count - 1; i >= 0; i--)
{
switch
(
this
[i])
{
case
global::Pure.DI.IOwned _:
break
;
case
global::System.IDisposable disposableInstance:
try
{
disposableInstance.Dispose();
}
catch
(global::System.Exception exception)
{
OnDisposeException(disposableInstance, exception);
}
break
;
#if NETCOREAPP3_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
case
global::System.IAsyncDisposable asyncDisposableInstance:
try
{
var
valueTask = asyncDisposableInstance.DisposeAsync();
if
(!valueTask.IsCompleted)
{
valueTask.AsTask().Wait();
}
}
catch
(global::System.Exception exception)
{
OnDisposeAsyncException(asyncDisposableInstance, exception);
}
break
;
#endif
}
}
}
finally
{
Clear();
}
}
#if NETCOREAPP3_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
/// <inheritdoc />
public
async
global::System.Threading.Tasks.ValueTask DisposeAsync()
{
if
(_isDisposed)
{
return
;
}
_isDisposed =
true
;
try
{
for
(
var
i = Count - 1; i >= 0; i--)
{
switch
(
this
[i])
{
case
global::Pure.DI.IOwned _:
break
;
case
global::System.IAsyncDisposable asyncDisposableInstance:
try
{
await
asyncDisposableInstance.DisposeAsync();
}
catch
(global::System.Exception exception)
{
OnDisposeAsyncException(asyncDisposableInstance, exception);
}
break
;
case
global::System.IDisposable disposableInstance:
try
{
disposableInstance.Dispose();
}
catch
(global::System.Exception exception)
{
OnDisposeException(disposableInstance, exception);
}
break
;
}
}
}
finally
{
Clear();
}
}
#endif
/// <summary>
/// Implement this partial method to handle the exception on disposing.
/// </summary>
/// <param name="disposableInstance">The disposable instance.</param>
/// <param name="exception">Exception occurring during disposal.</param>
/// <typeparam name="T">The actual type of instance being disposed of.</typeparam>
partial
void
OnDisposeException<T>(T disposableInstance, global::System.Exception exception)
where
T : global::System.IDisposable;
#if NETCOREAPP3_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
/// <summary>
/// Implement this partial method to handle the exception on disposing.
/// </summary>
/// <param name="asyncDisposableInstance">The disposable instance.</param>
/// <param name="exception">Exception occurring during disposal.</param>
/// <typeparam name="T">The actual type of instance being disposed of.</typeparam>
partial
void
OnDisposeAsyncException<T>(T asyncDisposableInstance, global::System.Exception exception)
where
T : global::System.IAsyncDisposable;
#endif
}
/// <summary>
/// Contains a value and gives the ability to dispose of that value.
/// </summary>
/// <typeparam name="T">Type of value owned.</typeparam>
[global::System.Diagnostics.DebuggerDisplay(
"{Value}"
)]
[global::System.Diagnostics.DebuggerTypeProxy(
typeof
(global::Pure.DI.Owned<>.DebugView))]
internal
readonly
struct
Owned<T>: global::Pure.DI.IOwned
{
/// <summary>
/// Own value.
/// </summary>
public
readonly
T Value;
private
readonly
global::Pure.DI.IOwned _owned;
/// <summary>
/// Creates a new instance.
/// </summary>
/// <param name="value">Own value.</param>
/// <param name="owned">The abstraction allows a disposable object to be disposed of.</param>
public
Owned(T value, global::Pure.DI.IOwned owned)
{
Value = value;
_owned = owned;
}
/// <inheritdoc />
public
void
Dispose()
{
_owned.Dispose();
}
#if NETCOREAPP3_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
/// <inheritdoc />
public
global::System.Threading.Tasks.ValueTask DisposeAsync()
{
return
_owned.DisposeAsync();
}
#endif
#if !NET20 && !NET35 && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && !NETCOREAPP1_0 && !NETCOREAPP1_1
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
private
class
DebugView
{
private
readonly
global::Pure.DI.Owned<T> _owned;
public
DebugView(global::Pure.DI.Owned<T> owned)
{
_owned = owned;
}
public
T Value
{
get
{
return
_owned.Value; }
}
[global::System.Diagnostics.DebuggerBrowsable(global::System.Diagnostics.DebuggerBrowsableState.Collapsed)]
public
global::Pure.DI.IOwned Owned
{
get
{
return
_owned._owned; }
}
}
}
/// <summary>
/// An API for a Dependency Injection setup.
/// </summary>
/// <seealso cref="DI.Setup"/>
internal
interface
IConfiguration
{
/// <summary>
/// Begins the binding definition for the implementation type itself, and if the implementation is not an abstract class or structure, for all abstract but NOT special types that are directly implemented.
/// Special types include:
/// <list type="bullet">
/// <item>System.Object</item>
/// <item>System.Enum</item>
/// <item>System.MulticastDelegate</item>
/// <item>System.Delegate</item>
/// <item>System.Collections.IEnumerable</item>
/// <item>System.Collections.Generic.IEnumerable<T></item>
/// <item>System.Collections.Generic.IList<T></item>
/// <item>System.Collections.Generic.ICollection<T></item>
/// <item>System.Collections.IEnumerator</item>
/// <item>System.Collections.Generic.IEnumerator<T></item>
/// <item>System.Collections.Generic.IIReadOnlyList<T></item>
/// <item>System.Collections.Generic.IReadOnlyCollection<T></item>
/// <item>System.IDisposable</item>
/// <item>System.IAsyncResult</item>
/// <item>System.AsyncCallback</item>
/// </list>
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind().To<Service>();
/// </code>
/// </example>
/// </summary>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind(
params
object
[] tags);
/// <summary>
/// Begins the definition of the binding.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IService>().To<Service>();
/// </code>
/// </example>
/// </summary>
/// <typeparam name="T">The type of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <typeparam name="T3">The type 3 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2, T3>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <typeparam name="T3">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T4">The type 4 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2, T3, T4>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <typeparam name="T3">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T4">The type 4 of dependency to be bound.</typeparam>
/// <typeparam name="T5">The type 5 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2, T3, T4, T5>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <typeparam name="T3">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T4">The type 4 of dependency to be bound.</typeparam>
/// <typeparam name="T5">The type 5 of dependency to be bound.</typeparam>
/// <typeparam name="T6">The type 6 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2, T3, T4, T5, T6>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <typeparam name="T3">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T4">The type 4 of dependency to be bound.</typeparam>
/// <typeparam name="T5">The type 5 of dependency to be bound.</typeparam>
/// <typeparam name="T6">The type 6 of dependency to be bound.</typeparam>
/// <typeparam name="T7">The type 7 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2, T3, T4, T5, T6, T7>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <typeparam name="T3">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T4">The type 4 of dependency to be bound.</typeparam>
/// <typeparam name="T5">The type 5 of dependency to be bound.</typeparam>
/// <typeparam name="T6">The type 6 of dependency to be bound.</typeparam>
/// <typeparam name="T7">The type 7 of dependency to be bound.</typeparam>
/// <typeparam name="T8">The type 8 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2, T3, T4, T5, T6, T7, T8>(
params
object
[] tags);
/// <summary>
/// Begins the definition of the binding with <see cref="Root{T}"/> applied.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .RootBind<IService>();
/// </code>
/// </example>
/// </summary>
/// <typeparam name="T">The type of dependency to be bound.</typeparam>
/// <param name="name">Specifies the unique name of the root of the composition. If the value is empty, a private root will be created, which can be used when calling <c>Resolve</c> methods.</param>
/// <param name="kind">The Optional argument specifying the kind for the root of the Composition.</param>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding. If is is not empty, the first tag is used for the root.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding RootBind<T>(
string
name =
""
, RootKinds kind = RootKinds.Default,
params
object
[] tags);
/// <summary>
/// Indicates the use of some single or multiple setups as base setups by name.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .DependsOn(nameof(CompositionBase));
/// </code>
/// </example>
/// </summary>
/// <param name="setupNames">A set of names for the basic setups on which this one depends.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="DI.Setup"/>
IConfiguration DependsOn(
params
string
[] setupNames);
/// <summary>
/// Specifies a custom generic type argument attribute.
/// <example>
/// <code>
/// [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct)]
/// class MyGenericTypeArgumentAttribute : Attribute;
///
/// [MyGenericTypeArgument]
/// interface TTMy;
///
/// DI.Setup("Composition")
/// .GenericTypeAttribute<MyGenericTypeArgumentAttribute>()
/// .Bind<IDependency<TTMy>>().To<Dependency<TTMy>>();
/// </code>
/// </example>
/// </summary>
/// <typeparam name="T">The attribute type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="GenericTypeArgumentAttribute"/>
IConfiguration GenericTypeArgumentAttribute<T>()
where
T : global::System.Attribute;
/// <summary>
/// Specifies a custom attribute that overrides the injection type.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .TypeAttribute<MyTypeAttribute>();
/// </code>
/// </example>
/// </summary>
/// <param name="typeArgumentPosition">The optional parameter that specifies the position of the type parameter in the attribute constructor. 0 by default. See predefined attribute <see cref="TypeAttribute{T}"/>.</param>
/// <typeparam name="T">The attribute type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="Pure.DI.TypeAttribute"/>
IConfiguration TypeAttribute<T>(
int
typeArgumentPosition = 0)
where
T : global::System.Attribute;
/// <summary>
/// Specifies a tag attribute that overrides the injected tag.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .TagAttribute<MyTagAttribute>();
/// </code>
/// </example>
/// </summary>
/// <param name="tagArgumentPosition">The optional parameter that specifies the position of the tag parameter in the attribute constructor. 0 by default. See the predefined <see cref="TagAttribute{T}"/> attribute.</param>
/// <typeparam name="T">The attribute type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="Pure.DI.TagAttribute"/>
IConfiguration TagAttribute<T>(
int
tagArgumentPosition = 0)
where
T : global::System.Attribute;
/// <summary>
/// Specifies a custom attribute that overrides the injection ordinal.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .OrdinalAttribute<MyOrdinalAttribute>();
/// </code>
/// </example>
/// </summary>
/// <param name="ordinalArgumentPosition">The optional parameter that specifies the position of the ordinal parameter in the attribute constructor. 0 by default. See the predefined <see cref="OrdinalAttribute{T}"/> attribute.</param>
/// <typeparam name="T">The attribute type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="Pure.DI.OrdinalAttribute"/>
IConfiguration OrdinalAttribute<T>(
int
ordinalArgumentPosition = 0)
where
T : global::System.Attribute;
/// <summary>
/// Overrides the default <see cref="Lifetime"/> for all bindings further down the chain. If not specified, the <see cref="Lifetime.Transient"/> lifetime is used.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .DefaultLifetime(Lifetime.Singleton);
/// </code>
/// </example>
/// </summary>
/// <param name="lifetime">The default lifetime.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="Lifetime"/>
/// <seealso cref="IBinding.As"/>
IConfiguration DefaultLifetime(Pure.DI.Lifetime lifetime);
/// <summary>
/// Overrides the default <see cref="Lifetime"/> for all bindings can be casted to type <typeparamref name="T"/> further down the chain.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .DefaultLifetime<IMySingleton>(Lifetime.Singleton);
/// </code>
/// <code>
/// DI.Setup("Composition")
/// .DefaultLifetime<IMySingleton>(Lifetime.Singleton, "my tag");
/// </code>
/// </example>
/// </summary>
/// <param name="lifetime">The default lifetime.</param>
/// <param name="tags">Optional argument specifying the binding tags for which it will set the default lifetime. If not specified, the default lifetime will be set for any tags.</param>
/// <typeparam name="T">The default lifetime will be applied to bindings if the implementation class can be cast to type <typeparamref name="T"/>.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="Lifetime"/>
/// <seealso cref="IBinding.As"/>
IConfiguration DefaultLifetime<T>(Pure.DI.Lifetime lifetime,
params
object
[] tags);
/// <summary>
/// Adds a partial class argument and replaces the default constructor by adding this argument as a parameter. It is only created if this argument is actually used.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Arg<int>("id");
/// </code>
/// </example>
/// </summary>
/// <param name="name">The argument name.</param>
/// <param name="tags">The optional argument that specifies the tags for the argument.</param>
/// <typeparam name="T">The argument type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
IConfiguration Arg<T>(
string
name,
params
object
[] tags);
/// <summary>
/// Adds a root argument to use as a root parameter.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .RootArg<int>("id");
/// </code>
/// </example>
/// </summary>
/// <param name="name">The argument name.</param>
/// <param name="tags">The optional argument that specifies the tags for the argument.</param>
/// <typeparam name="T">The argument type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
IConfiguration RootArg<T>(
string
name,
params
object
[] tags);
/// <summary>
/// Specifying the root of the Composition.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Root<Service>("MyService");
/// </code>
/// </example>
/// </summary>
/// <param name="name">Specifies the unique name of the root of the composition. If the value is empty, a private root will be created, which can be used when calling <c>Resolve</c> methods.</param>
/// <param name="tag">Optional argument specifying the tag for the root of the Composition.</param>
/// <typeparam name="T">The Composition root type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
IConfiguration Root<T>(
string
name =
""
,
object
tag =
null
, RootKinds kind = RootKinds.Default);
/// <summary>
/// Defines a hint for fine-tuning code generation.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Hint(Resolve, "Off");
/// </code>
/// </example>
/// </summary>
/// <param name="hint">The hint type.</param>
/// <param name="value">The hint value.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="Pure.DI.Hint"/>
IConfiguration Hint(Hint hint,
string
value);
/// <summary>
/// Registers an accumulator for instances.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Accumulate<IDisposable, MyAccumulator>(Lifetime.Transient);
/// </code>
/// </example>
/// </summary>
/// <param name="lifetimes"><see cref="Lifetime"/> of the instances to be accumulated. Instances with lifetime <see cref="Lifetime.Singleton"/>, <see cref="Lifetime.Scoped"/>, or <see cref="Lifetime.PerResolve"/> only accumulate in an accumulator that is NOT lazily created.</param>
/// <typeparam name="T">The type of instance. All instances that can be cast to this type will be aacumulated.</typeparam>
/// <typeparam name="TAccumulator">The type of accumulator. It must have a public constructor without parameters and a <c>Add</c> method with a single argument that allows you to add an instance of type <typeparamref name="T"/>.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="Pure.DI.Hint"/>
/// <seealso cref="Pure.DI.Lifetime"/>
IConfiguration Accumulate<T, TAccumulator>(
params
Lifetime[] lifetimes)
where
TAccumulator:
new
();
/// <summary>
/// Specifies a custom generic type argument.
/// <example>
/// <code>
/// interface TTMy;
///
/// DI.Setup("Composition")
/// .GenericTypeArgument<TTMy>()
/// .Bind<IDependency<TTMy>>().To<Dependency<TTMy>>();
/// </code>
/// </example>
/// </summary>
/// <typeparam name="T">The generic type marker.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
IConfiguration GenericTypeArgument<T>();
}
/// <summary>
/// An API for a binding setup.
/// </summary>
internal
interface
IBinding
{
/// <summary>
/// Begins the binding definition for the implementation type itself, and if the implementation is not an abstract class or structure, for all abstract but NOT special types that are directly implemented.
/// Special types include:
/// <list type="bullet">
/// <item>System.Object</item>
/// <item>System.Enum</item>
/// <item>System.MulticastDelegate</item>
/// <item>System.Delegate</item>
/// <item>System.Collections.IEnumerable</item>
/// <item>System.Collections.Generic.IEnumerable<T></item>
/// <item>System.Collections.Generic.IList<T></item>
/// <item>System.Collections.Generic.ICollection<T></item>
/// <item>System.Collections.IEnumerator</item>
/// <item>System.Collections.Generic.IEnumerator<T></item>
/// <item>System.Collections.Generic.IIReadOnlyList<T></item>
/// <item>System.Collections.Generic.IReadOnlyCollection<T></item>
/// <item>System.IDisposable</item>
/// <item>System.IAsyncResult</item>
/// <item>System.AsyncCallback</item>
/// </list>
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind().To<Service>();
/// </code>
/// </example>
/// </summary>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind(
params
object
[] tags);
/// <summary>
/// Begins the definition of the binding.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <typeparam name="T">The type of dependency to be bound. Common type markers such as <see cref="TT"/>, <see cref="TTList{T}"/> and others are also supported.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <typeparam name="T3">The type 3 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2, T3>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <typeparam name="T3">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T4">The type 3 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2, T3, T4>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <typeparam name="T3">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T4">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T5">The type 5 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2, T3, T4, T5>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <typeparam name="T3">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T4">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T5">The type 5 of dependency to be bound.</typeparam>
/// <typeparam name="T6">The type 6 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2, T3, T4, T5, T6>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <typeparam name="T3">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T4">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T5">The type 5 of dependency to be bound.</typeparam>
/// <typeparam name="T6">The type 6 of dependency to be bound.</typeparam>
/// <typeparam name="T7">The type 7 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2, T3, T4, T5, T6, T7>(
params
object
[] tags);
/// <summary>
/// Begins binding definition for multiple dependencies. See <see cref="Bind{T}"/> for examples.
/// </summary>
/// <typeparam name="T1">The type 1 of dependency to be bound.</typeparam>
/// <typeparam name="T2">The type 2 of dependency to be bound.</typeparam>
/// <typeparam name="T3">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T4">The type 3 of dependency to be bound.</typeparam>
/// <typeparam name="T5">The type 5 of dependency to be bound.</typeparam>
/// <typeparam name="T6">The type 6 of dependency to be bound.</typeparam>
/// <typeparam name="T7">The type 7 of dependency to be bound.</typeparam>
/// <typeparam name="T8">The type 8 of dependency to be bound.</typeparam>
/// <param name="tags">The optional argument that specifies tags for a particular type of dependency binding.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IBinding Bind<T1, T2, T3, T4, T5, T6, T7, T8>(
params
object
[] tags);
/// <summary>
/// Determines the <see cref="Lifetime"/> of a binding.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IDependency>().As(Lifetime.Singleton).To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <param name="lifetime">The <see cref="Lifetime"/> of a binding</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="IConfiguration.Bind{T}"/>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
IBinding As(Pure.DI.Lifetime lifetime);
/// <summary>
/// Defines the binding tags.
/// <example>
/// Sometimes it's important to take control of building a dependency graph. For example, when there are multiple implementations of the same contract. In this case, tags will help:
/// <code>
/// interface IDependency { }
///
///
/// class AbcDependency : IDependency { }
///
///
/// class XyzDependency : IDependency { }
///
///
/// class Dependency : IDependency { }
///
///
/// interface IService
/// {
/// IDependency Dependency1 { get; }
///
///
/// IDependency Dependency2 { get; }
/// }
///
///
/// class Service : IService
/// {
/// public Service(
/// [Tag("Abc")] IDependency dependency1,
/// [Tag("Xyz")] IDependency dependency2)
/// {
/// Dependency1 = dependency1;
/// Dependency2 = dependency2;
/// }
///
/// public IDependency Dependency1 { get; }
///
///
/// public IDependency Dependency2 { get; }
/// }
///
///
/// DI.Setup("Composition")
/// .Bind<IDependency>().Tags("Abc").To<AbcDependency>()
/// .Bind<IDependency>().Tags("Xyz").To<XyzDependency>()
/// .Bind<IService>().To<Service>().Root<IService>("Root");
/// </code>
/// </example>
/// </summary>
/// <param name="tags">The binding tags.</param>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="IConfiguration.Bind{T}"/>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="As"/>
IBinding Tags(
params
object
[] tags);
/// <summary>
/// Completes the binding chain by specifying the implementation.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>();
/// </code>
/// </example>
/// </summary>
/// <typeparam name="T">The implementation type. Also supports generic type markers such as <see cref="TT"/>, <see cref="TTList{T}"/>, and others.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="IConfiguration.Bind{T}"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IConfiguration To<T>();
/// <summary>
/// Completes the binding chain by specifying the implementation using a factory method. It allows you to manually create an instance, call the necessary methods, initialize properties, fields, etc.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IService>()
/// To(_ =>
/// {
/// var service = new Service("My Service");
/// service.Initialize();
/// return service;
/// })
/// </code>
/// <br/>
/// another example:
/// <code>
/// DI.Setup("Composition")
/// .Bind&lt;IService&gt;()
/// To(ctx =&gt;
/// {
/// ctx.Inject<IDependency>(out var dependency);
/// return new Service(dependency);
/// })
/// </code>
/// <br/>
/// and another example:
/// <code>
/// DI.Setup("Composition")
/// .Bind&lt;IService&gt;()
/// To(ctx =&gt;
/// {
/// // Builds up an instance with all necessary dependencies
/// ctx.Inject<Service>(out var service);
///
///
/// service.Initialize();
/// return service;
/// })
/// </code>
/// </example>
/// </summary>
/// <param name="factory">An expression for manually creating and initializing an instance.</param>
/// <typeparam name="T">The implementation type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="IConfiguration.Bind{T}"/>
/// <seealso cref="To{T}()"/>
/// <seealso cref="To{T1,T}()"/>
/// <seealso cref="To{T1,T2,T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IConfiguration To<T>(global::System.Func<IContext, T> factory);
/// <summary>
/// Completes the binding chain by specifying the implementation using a source code statement.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<int>().To<int>("dependencyId")
/// .Bind<Func<int, IDependency>>()
/// .To<Func<int, IDependency>>(ctx =>
/// dependencyId =>
/// {
/// ctx.Inject<Dependency>(out var dependency);
/// return dependency;
/// });
/// </code>
/// </example>
/// </summary>
/// <param name="sourceCodeStatement">Source code statement</param>
/// <typeparam name="T">The implementation type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="IConfiguration.Bind{T}"/>
IConfiguration To<T>(
string
sourceCodeStatement);
/// <summary>
/// Completes the binding chain by specifying the implementation using a simplified factory method. It allows you to manually create an instance, call the necessary methods, initialize properties, fields, etc. Each parameter of this factory method represents a dependency injection. Starting with C# 10, you can also put the <see cref="TagAttribute"/> in front of the parameter to specify the tag of the injected dependency.
/// <example>
/// <code>
/// DI.Setup(nameof(Composition))
/// .Bind<IDependency>().To((
/// Dependency dependency) =>
/// {
/// dependency.Initialize();
/// return dependency;
/// });
/// </code>
/// A variant using <see cref="TagAttribute"/>:
/// <code>
/// DI.Setup(nameof(Composition))
/// .Bind<IDependency>().To((
/// [Tag("some tag")] Dependency dependency) =>
/// {
/// dependency.Initialize();
/// return dependency;
/// });
/// </code>
/// </example>
/// </summary>
/// <param name="factory">An expression for manually creating and initializing an instance.</param>
/// <typeparam name="T1">Type #1 of injected dependency.</typeparam>
/// <typeparam name="T">The implementation type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="IConfiguration.Bind{T}"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IConfiguration To<T1, T>(global::System.Func<T1, T> factory);
/// <summary>
/// Completes the binding chain by specifying the implementation using a simplified factory method. It allows you to manually create an instance, call the necessary methods, initialize properties, fields, etc. Each parameter of this factory method represents a dependency injection. Starting with C# 10, you can also put the <see cref="TagAttribute"/> in front of the parameter to specify the tag of the injected dependency.
/// <example>
/// <code>
/// DI.Setup(nameof(Composition))
/// .Bind<IDependency>().To((
/// Dependency dependency,
/// DateTimeOffset time) =>
/// {
/// dependency.Initialize(time);
/// return dependency;
/// });
/// </code>
/// A variant using <see cref="TagAttribute"/>:
/// <code>
/// DI.Setup(nameof(Composition))
/// .Bind("now datetime").To(_ => DateTimeOffset.Now)
/// .Bind<IDependency>().To((
/// Dependency dependency,
/// [Tag("now datetime")] DateTimeOffset time) =>
/// {
/// dependency.Initialize(time);
/// return dependency;
/// });
/// </code>
/// </example>
/// </summary>
/// <param name="factory">An expression for manually creating and initializing an instance.</param>
/// <typeparam name="T1">Type #1 of injected dependency.</typeparam>
/// <typeparam name="T2">Type #2 of injected dependency.</typeparam>
/// <typeparam name="T">The implementation type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="IConfiguration.Bind{T}"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IConfiguration To<T1, T2, T>(global::System.Func<T1, T2, T> factory);
/// <summary>
/// Completes the binding chain by specifying the implementation using a simplified factory method. It allows you to manually create an instance, call the necessary methods, initialize properties, fields, etc. Each parameter of this factory method represents a dependency injection. Starting with C# 10, you can also put the <see cref="TagAttribute"/> in front of the parameter to specify the tag of the injected dependency.
/// </summary>
/// <param name="factory">An expression for manually creating and initializing an instance.</param>
/// <typeparam name="T1">Type #1 of injected dependency.</typeparam>
/// <typeparam name="T2">Type #2 of injected dependency.</typeparam>
/// <typeparam name="T3">Type #3 of injected dependency.</typeparam>
/// <typeparam name="T">The implementation type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="IConfiguration.Bind{T}"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IConfiguration To<T1, T2, T3, T>(global::System.Func<T1, T2, T3, T> factory);
/// <summary>
/// Completes the binding chain by specifying the implementation using a simplified factory method. It allows you to manually create an instance, call the necessary methods, initialize properties, fields, etc. Each parameter of this factory method represents a dependency injection. Starting with C# 10, you can also put the <see cref="TagAttribute"/> in front of the parameter to specify the tag of the injected dependency.
/// </summary>
/// <param name="factory">An expression for manually creating and initializing an instance.</param>
/// <typeparam name="T1">Type #1 of injected dependency.</typeparam>
/// <typeparam name="T2">Type #2 of injected dependency.</typeparam>
/// <typeparam name="T3">Type #3 of injected dependency.</typeparam>
/// <typeparam name="T4">Type #4 of injected dependency.</typeparam>
/// <typeparam name="T">The implementation type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="IConfiguration.Bind{T}"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IConfiguration To<T1, T2, T3, T4, T>(global::System.Func<T1, T2, T3, T4, T> factory);
/// <summary>
/// Completes the binding chain by specifying the implementation using a simplified factory method. It allows you to manually create an instance, call the necessary methods, initialize properties, fields, etc. Each parameter of this factory method represents a dependency injection. Starting with C# 10, you can also put the <see cref="TagAttribute"/> in front of the parameter to specify the tag of the injected dependency.
/// </summary>
/// <param name="factory">An expression for manually creating and initializing an instance.</param>
/// <typeparam name="T1">Type #1 of injected dependency.</typeparam>
/// <typeparam name="T2">Type #2 of injected dependency.</typeparam>
/// <typeparam name="T3">Type #3 of injected dependency.</typeparam>
/// <typeparam name="T4">Type #4 of injected dependency.</typeparam>
/// <typeparam name="T5">Type #5 of injected dependency.</typeparam>
/// <typeparam name="T">The implementation type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="IConfiguration.Bind{T}"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IConfiguration To<T1, T2, T3, T4, T5, T>(global::System.Func<T1, T2, T3, T4, T5, T> factory);
/// <summary>
/// Completes the binding chain by specifying the implementation using a simplified factory method. It allows you to manually create an instance, call the necessary methods, initialize properties, fields, etc. Each parameter of this factory method represents a dependency injection. Starting with C# 10, you can also put the <see cref="TagAttribute"/> in front of the parameter to specify the tag of the injected dependency.
/// </summary>
/// <param name="factory">An expression for manually creating and initializing an instance.</param>
/// <typeparam name="T1">Type #1 of injected dependency.</typeparam>
/// <typeparam name="T2">Type #2 of injected dependency.</typeparam>
/// <typeparam name="T3">Type #3 of injected dependency.</typeparam>
/// <typeparam name="T4">Type #4 of injected dependency.</typeparam>
/// <typeparam name="T5">Type #5 of injected dependency.</typeparam>
/// <typeparam name="T6">Type #6 of injected dependency.</typeparam>
/// <typeparam name="T">The implementation type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="IConfiguration.Bind{T}"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IConfiguration To<T1, T2, T3, T4, T5, T6, T>(global::System.Func<T1, T2, T3, T4, T5, T6, T> factory);
/// <summary>
/// Completes the binding chain by specifying the implementation using a simplified factory method. It allows you to manually create an instance, call the necessary methods, initialize properties, fields, etc. Each parameter of this factory method represents a dependency injection. Starting with C# 10, you can also put the <see cref="TagAttribute"/> in front of the parameter to specify the tag of the injected dependency.
/// </summary>
/// <param name="factory">An expression for manually creating and initializing an instance.</param>
/// <typeparam name="T1">Type #1 of injected dependency.</typeparam>
/// <typeparam name="T2">Type #2 of injected dependency.</typeparam>
/// <typeparam name="T3">Type #3 of injected dependency.</typeparam>
/// <typeparam name="T4">Type #4 of injected dependency.</typeparam>
/// <typeparam name="T5">Type #5 of injected dependency.</typeparam>
/// <typeparam name="T6">Type #6 of injected dependency.</typeparam>
/// <typeparam name="T7">Type #7 of injected dependency.</typeparam>
/// <typeparam name="T">The implementation type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="IConfiguration.Bind{T}"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IConfiguration To<T1, T2, T3, T4, T5, T6, T7, T>(global::System.Func<T1, T2, T3, T4, T5, T6, T7, T> factory);
/// <summary>
/// Completes the binding chain by specifying the implementation using a simplified factory method. It allows you to manually create an instance, call the necessary methods, initialize properties, fields, etc. Each parameter of this factory method represents a dependency injection. Starting with C# 10, you can also put the <see cref="TagAttribute"/> in front of the parameter to specify the tag of the injected dependency.
/// </summary>
/// <param name="factory">An expression for manually creating and initializing an instance.</param>
/// <typeparam name="T1">Type #1 of injected dependency.</typeparam>
/// <typeparam name="T2">Type #2 of injected dependency.</typeparam>
/// <typeparam name="T3">Type #3 of injected dependency.</typeparam>
/// <typeparam name="T4">Type #4 of injected dependency.</typeparam>
/// <typeparam name="T5">Type #5 of injected dependency.</typeparam>
/// <typeparam name="T6">Type #6 of injected dependency.</typeparam>
/// <typeparam name="T7">Type #7 of injected dependency.</typeparam>
/// <typeparam name="T8">Type #7 of injected dependency.</typeparam>
/// <typeparam name="T">The implementation type.</typeparam>
/// <returns>Reference to the setup continuation chain.</returns>
/// <seealso cref="IConfiguration.Bind{T}"/>
/// <seealso cref="To{T}(System.Func{Pure.DI.IContext,T})"/>
/// <seealso cref="To{T}()"/>
/// <seealso cref="Tags"/>
/// <seealso cref="As"/>
IConfiguration To<T1, T2, T3, T4, T5, T6, T7, T8, T>(global::System.Func<T1, T2, T3, T4, T5, T6, T7, T8, T> factory);
}
/// <summary>
/// Injection context. Cannot be used outside of the binding setup.
/// </summary>
internal
interface
IContext
{
/// <summary>
/// The tag that was used to inject the current object in the object graph. Cannot be used outside of the binding setup. See also <see cref="IBinding.Tags"/>
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<Lazy<TT>>()
/// .To(ctx =>
/// {
/// ctx.Inject<Func<TT>>(ctx.Tag, out var func);
/// return new Lazy<TT>(func, false);
/// };
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IConfiguration.Bind{T}"/>
/// <seealso cref="IBinding.Tags"/>
object
Tag {
get
; }
/// <summary>
/// The types of consumers for which the instance is created. Cannot be used outside of the binding setup. Guaranteed to contain at least one element.
/// </summary>
/// <seealso cref="IConfiguration.Bind{T}"/>
Type[] ConsumerTypes {
get
; }
/// <summary>
/// Injects an instance of type <c>T</c>. Cannot be used outside of the binding setup.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IService>()
/// To(ctx =>
/// {
/// ctx.Inject<IDependency>(out var dependency);
/// return new Service(dependency);
/// })
/// </code>
/// <br/>
/// and another example:<br/>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IService>()
/// To(ctx =>
/// {
/// // Builds up an instance with all necessary dependencies
/// ctx.Inject<Service>(out var service);
///
///
/// service.Initialize();
/// return service;
/// })
/// </code>
/// </example>
/// </summary>
/// <param name="value">Injectable instance.</param>.
/// <typeparam name="T">Instance type.</typeparam>
/// <seealso cref="IBinding.To{T}(System.Func{Pure.DI.IContext,T})"/>
void
Inject<T>(
out
T value);
/// <summary>
/// Injects an instance of type <c>T</c> marked with a tag. Cannot be used outside of the binding setup.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IService>()
/// To(ctx =>
/// {
/// ctx.Inject<IDependency>("MyTag", out var dependency);
/// return new Service(dependency);
/// })
/// </code>
/// </example>
/// </summary>
/// <param name="tag">The injection tag. See also <see cref="IBinding.Tags"/></param>.
/// <param name="value">Injectable instance.</param>.
/// <typeparam name="T">Instance type.</typeparam>
/// <seealso cref="IBinding.To{T}(System.Func{Pure.DI.IContext,T})"/>
void
Inject<T>(
object
tag,
out
T value);
/// <summary>
/// Builds up of an existing object. In other words, injects the necessary dependencies via methods, properties, or fields into an existing object. Cannot be used outside of the binding setup.
/// <example>
/// <code>
/// DI.Setup("Composition")
/// .Bind<IService>()
/// To(ctx =>
/// {
/// var service = new Service();
/// // Initialize an instance with all necessary dependencies
/// ctx.BuildUp(service);
///
///
/// return service;
/// })
/// </code>
/// </example>
/// </summary>
/// <param name="value">An existing object for which the injection(s) is to be performed.</param>
/// <typeparam name="T">Object type.</typeparam>
void
BuildUp<T>(T value);
}
/// <summary>
/// An API for a Dependency Injection setup.
/// </summary>
/// <seealso cref="Setup"/>
#if !NET20 && !NET35 && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && !NETCOREAPP1_0 && !NETCOREAPP1_1
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
internal
static
class
DI
{
/// <summary>
/// Begins the definitions of the Dependency Injection setup chain.
/// <example>
/// <code>
/// interface IDependency;
///
///
/// class Dependency : IDependency;
///
///
/// interface IService;
///
///
/// class Service(IDependency dependency) : IService;
///
///
/// DI.Setup("Composition")
/// .Bind<IDependency>().To<Dependency>()
/// .Bind<IService>().To<Service>()
/// .Root<IService>("Root");
/// </code>
/// </example>
/// </summary>
/// <param name="compositionTypeName">An optional argument specifying the partial class name to generate.</param>
/// <param name="kind">An optional argument specifying the kind of setup. Please <see cref="Pure.DI.CompositionKind"/> for details. It defaults to <c>Public</c>.</param>
/// <returns>Reference to the setup continuation chain.</returns>
internal
static
IConfiguration Setup(
string
compositionTypeName =
""
, CompositionKind kind = CompositionKind.Public)
{
return
Configuration.Shared;
}
#if !NET20 && !NET35 && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && !NETCOREAPP1_0 && !NETCOREAPP1_1
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
private
sealed
class
Configuration : IConfiguration
{
public
static
readonly
IConfiguration Shared =
new
Configuration();
private
Configuration() { }
/// <inheritdoc />
public
IBinding Bind(
params
object
[] tags)
{
return
Binding.Shared;
}
/// <inheritdoc />
public
IBinding Bind<T>(
params
object
[] tags)
{
return
Binding.Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2>(
params
object
[] tags)
{
return
Binding.Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2, T3>(
params
object
[] tags)
{
return
Binding.Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2, T3, T4>(
params
object
[] tags)
{
return
Binding.Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2, T3, T4, T5>(
params
object
[] tags)
{
return
Binding.Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2, T3, T4, T5, T6>(
params
object
[] tags)
{
return
Binding.Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2, T3, T4, T5, T6, T7>(
params
object
[] tags)
{
return
Binding.Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2, T3, T4, T5, T6, T7, T8>(
params
object
[] tags)
{
return
Binding.Shared;
}
/// <inheritdoc />
public
IBinding RootBind<T>(
string
name =
""
, RootKinds kind = RootKinds.Default,
params
object
[] tags)
{
return
Binding.Shared;
}
/// <inheritdoc />
public
IConfiguration DependsOn(
params
string
[] setupNames)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration GenericTypeArgumentAttribute<T>()
where
T : global::System.Attribute
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration TypeAttribute<T>(
int
typeArgumentPosition = 0)
where
T : global::System.Attribute
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration TagAttribute<T>(
int
tagArgumentPosition = 0)
where
T : global::System.Attribute
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration OrdinalAttribute<T>(
int
ordinalArgumentPosition = 0)
where
T : global::System.Attribute
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration DefaultLifetime(Pure.DI.Lifetime lifetime)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration DefaultLifetime<T>(Lifetime lifetime,
params
object
[] tags)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration Arg<T>(
string
name,
params
object
[] tags)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration RootArg<T>(
string
name,
params
object
[] tags)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration Root<T>(
string
name,
object
tag, RootKinds rootKind)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration Hint(Hint hint,
string
value)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration Accumulate<T, TAccumulator>(
params
Lifetime[] lifetimes)
where
TAccumulator:
new
()
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration GenericTypeArgument<T>()
{
return
Configuration.Shared;
}
}
private
sealed
class
Binding : IBinding
{
public
static
readonly
IBinding Shared =
new
Binding();
private
Binding() { }
/// <inheritdoc />
public
IBinding Bind(
params
object
[] tags)
{
return
Shared;
}
/// <inheritdoc />
public
IBinding Bind<T>(
params
object
[] tags)
{
return
Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2>(
params
object
[] tags)
{
return
Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2, T3>(
params
object
[] tags)
{
return
Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2, T3, T4>(
params
object
[] tags)
{
return
Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2, T3, T4, T5>(
params
object
[] tags)
{
return
Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2, T3, T4, T5, T6>(
params
object
[] tags)
{
return
Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2, T3, T4, T5, T6, T7>(
params
object
[] tags)
{
return
Shared;
}
/// <inheritdoc />
public
IBinding Bind<T1, T2, T3, T4, T5, T6, T7, T8>(
params
object
[] tags)
{
return
Shared;
}
/// <inheritdoc />
public
IBinding As(Pure.DI.Lifetime lifetime)
{
return
Shared;
}
/// <inheritdoc />
public
IBinding Tags(
params
object
[] tags)
{
return
Shared;
}
/// <inheritdoc />
public
IConfiguration To<T>()
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration To<T>(global::System.Func<IContext, T> factory)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration To<T>(
string
sourceCodeStatement)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration To<T1, T>(global::System.Func<T1, T> factory)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration To<T1, T2, T>(global::System.Func<T1, T2, T> factory)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration To<T1, T2, T3, T>(global::System.Func<T1, T2, T3, T> factory)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration To<T1, T2, T3, T4, T>(Func<T1, T2, T3, T4, T> factory)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration To<T1, T2, T3, T4, T5, T>(Func<T1, T2, T3, T4, T5, T> factory)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration To<T1, T2, T3, T4, T5, T6, T>(Func<T1, T2, T3, T4, T5, T6, T> factory)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration To<T1, T2, T3, T4, T5, T6, T7, T>(Func<T1, T2, T3, T4, T5, T6, T7, T> factory)
{
return
Configuration.Shared;
}
/// <inheritdoc />
public
IConfiguration To<T1, T2, T3, T4, T5, T6, T7, T8, T>(Func<T1, T2, T3, T4, T5, T6, T7, T8, T> factory)
{
return
Configuration.Shared;
}
}
}
/// <summary>
/// For internal use.
/// </summary>
#if !NET20 && !NET35 && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && !NETCOREAPP1_0 && !NETCOREAPP1_1
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
[global::System.Runtime.InteropServices.StructLayout(global::System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 1)]
internal
struct
Pair<TKey, TValue>
{
public
readonly
TKey Key;
public
readonly
TValue Value;
public
Pair(TKey key, TValue value)
{
Key = key;
Value = value;
}
public
override
string
ToString()
{
return
Key?.ToString() ??
"empty"
+
" = "
+ Value.ToString();
}
}
/// <summary>
/// For internal use.
/// </summary>
#if !NET20 && !NET35 && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && !NETCOREAPP1_0 && !NETCOREAPP1_1
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
internal
static
class
Buckets<TKey, TValue>
{
public
static
uint
GetDivisor(
uint
count)
{
return
count < 2 ? count : count << 1;
}
public
static
Pair<TKey, TValue>[] Create(
uint
divisor,
out
int
bucketSize,
Pair<TKey, TValue>[] pairs)
{
bucketSize = 0;
int
[] bucketSizes =
new
int
[divisor];
for
(
int
i = 0; i < pairs.Length; i++)
{
int
bucket = (
int
)(((
uint
)global::System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(pairs[i].Key)) % divisor);
int
size = bucketSizes[bucket] + 1;
bucketSizes[bucket] = size;
if
(size > bucketSize)
{
bucketSize = size;
}
}
Pair<TKey, TValue>[] buckets =
new
Pair<TKey, TValue>[divisor * bucketSize];
for
(
int
i = 0; i < pairs.Length; i++)
{
int
bucket = (
int
)(((
uint
)global::System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(pairs[i].Key)) % divisor);
var
index = bucketSizes[bucket];
buckets[bucket * bucketSize + bucketSize - index] = pairs[i];
bucketSizes[bucket] = index - 1;
}
return
buckets;
}
}
/// <summary>
/// Abstract dependency resolver.
/// </summary>
/// <typeparam name="TComposite">The composition type.</typeparam>
/// <typeparam name="T">The type of the composition root.</typeparam>
internal
interface
IResolver<TComposite,
out
T>
{
/// <summary>
/// Resolves the composition root.
/// </summary>
/// <param name="composite">The composition.</param>
/// <returns>A composition root.</returns>
T Resolve(TComposite composite);
/// <summary>
/// Resolves the composition root by type and tag.
/// </summary>
/// <param name="composite">The composition.</param>
/// <param name="tag">The tag of a composition root.</param>
/// <returns>A composition root.</returns>
T ResolveByTag(TComposite composite,
object
tag);
}
}
#pragma warning restore
#endif