mirror of
https://github.com/Stone-Red-Code/DynamicInjector.git
synced 2026-09-04 00:56:04 +02:00
- Add documentation
This commit is contained in:
@@ -17,8 +17,8 @@ internal class Prgramm
|
||||
int res = scope.Invoke<TestClass, int, SecondTestService>(testClass, (i) => i.SecondTest);
|
||||
|
||||
Console.WriteLine(res);
|
||||
scope.Invoke<TestClass>(testClass, (i) => i.SecondTest);
|
||||
scope.Invoke<TestClass>(testClass, (i) => i.SecondTest);
|
||||
scope.Invoke(testClass, (i) => i.SecondTest);
|
||||
scope.Invoke(testClass, (i) => i.SecondTest);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Vsxmd" Version="1.4.5">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -2,12 +2,32 @@
|
||||
|
||||
namespace DynamicInjector
|
||||
{
|
||||
/// <summary>
|
||||
/// Container
|
||||
/// </summary>
|
||||
public interface IContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoke method in class and resolve services
|
||||
/// </summary>
|
||||
/// <typeparam name="TInstance"></typeparam>
|
||||
/// <param name="instance"></param>
|
||||
/// <param name="method"></param>
|
||||
/// <returns>The result of the specified method</returns>
|
||||
public object Invoke<TInstance>(TInstance instance, Func<TInstance, Delegate> method);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an instance of a class with all resolved services from the service container
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns>A class with all resolved services</returns>
|
||||
public object Resolve(Type type);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an instance of a class with all resolved services
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns>A class with all resolved services</returns>
|
||||
public T Resolve<T>();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace DynamicInjector
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the associated property should have a value injected from the service container during initialization.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
|
||||
public class InjectAttribute : Attribute
|
||||
{
|
||||
|
||||
@@ -4,22 +4,44 @@ using System.Reflection;
|
||||
|
||||
namespace DynamicInjector
|
||||
{
|
||||
/// <summary>
|
||||
/// Container which handles all registered services
|
||||
/// </summary>
|
||||
public class InjectionContainer : IContainer
|
||||
{
|
||||
private readonly Dictionary<string, object> globalServices = new Dictionary<string, object>();
|
||||
private readonly Dictionary<string, Type> localServices = new Dictionary<string, Type>();
|
||||
private readonly Dictionary<string, Type> scopedServices = new Dictionary<string, Type>();
|
||||
|
||||
/// <summary>
|
||||
/// Registers a global service
|
||||
/// </summary>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
/// <param name="name"></param>
|
||||
public void RegisterGlobal<TService>(string? name = null)
|
||||
{
|
||||
globalServices.Add(name ?? typeof(TService).FullName, Resolve<TService>()!);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a global service
|
||||
/// </summary>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
/// <typeparam name="TImplementation"></typeparam>
|
||||
/// <param name="name"></param>
|
||||
public void RegisterGlobal<TService, TImplementation>(string? name = null) where TImplementation : TService
|
||||
{
|
||||
globalServices.Add(name ?? typeof(TService).FullName, Resolve<TImplementation>()!);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a global service
|
||||
/// </summary>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
/// <typeparam name="TImplementation"></typeparam>
|
||||
/// <param name="implementation"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public void RegisterGlobal<TService, TImplementation>(TImplementation implementation, string? name = null) where TImplementation : TService
|
||||
{
|
||||
if (implementation is null)
|
||||
@@ -30,36 +52,64 @@ namespace DynamicInjector
|
||||
globalServices.Add(name ?? typeof(TService).FullName, implementation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a local service
|
||||
/// </summary>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
/// <param name="name"></param>
|
||||
public void RegisterLocal<TService>(string? name = null)
|
||||
{
|
||||
localServices.Add(name ?? typeof(TService).FullName, typeof(TService));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a local service
|
||||
/// </summary>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
/// <typeparam name="TImplementation"></typeparam>
|
||||
/// <param name="name"></param>
|
||||
public void RegisterLocal<TService, TImplementation>(string? name = null) where TImplementation : TService
|
||||
{
|
||||
localServices.Add(name ?? typeof(TService).FullName, typeof(TImplementation));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a scoped service
|
||||
/// </summary>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
/// <param name="name"></param>
|
||||
public void RegisterScoped<TService>(string? name = null)
|
||||
{
|
||||
scopedServices.Add(name ?? typeof(TService).FullName, typeof(TService));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a scoped service
|
||||
/// </summary>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
/// <typeparam name="TImplementation"></typeparam>
|
||||
/// <param name="name"></param>
|
||||
public void RegisterScoped<TService, TImplementation>(string? name = null) where TImplementation : TService
|
||||
{
|
||||
scopedServices.Add(name ?? typeof(TService).FullName, typeof(TImplementation));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Begins a new scope
|
||||
/// </summary>
|
||||
/// <returns>A new scope</returns>
|
||||
public LifetimeScope BeginScope()
|
||||
{
|
||||
return new LifetimeScope(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Resolve{T}"/>
|
||||
public T Resolve<T>()
|
||||
{
|
||||
return (T)Resolve(typeof(T));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Resolve(Type)"/>
|
||||
public object Resolve(Type type)
|
||||
{
|
||||
return InternalResolve(type, null);
|
||||
@@ -76,7 +126,7 @@ namespace DynamicInjector
|
||||
|
||||
if (constructorInfos.Length > 1)
|
||||
{
|
||||
throw new InvalidOperationException($"Service \"{type.FullName}\" contains multiple constructors!");
|
||||
throw new InvalidOperationException($"Service \"{type.FullName}\" cannot contain multiple constructors!");
|
||||
}
|
||||
|
||||
ConstructorInfo constructorInfo = constructorInfos[0];
|
||||
@@ -132,6 +182,7 @@ namespace DynamicInjector
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public object Invoke<TInstance>(TInstance instance, Func<TInstance, Delegate> method)
|
||||
{
|
||||
return InternalInvoke(instance, method, null);
|
||||
@@ -162,7 +213,7 @@ namespace DynamicInjector
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException($"Service \"{parameterInfo.ParameterType.FullName}\" not found!");
|
||||
throw new InvalidOperationException($"Cannot find service \"{parameterInfo.ParameterType.FullName}\"!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,32 +3,41 @@ using System.Collections.Generic;
|
||||
|
||||
namespace DynamicInjector
|
||||
{
|
||||
/// <summary>
|
||||
/// A scope
|
||||
/// </summary>
|
||||
public class LifetimeScope : IContainer, IDisposable
|
||||
{
|
||||
private readonly InjectionContainer injectionContainer;
|
||||
|
||||
public Dictionary<string, object> Services { get; } = new Dictionary<string, object>();
|
||||
internal Dictionary<string, object> Services { get; } = new Dictionary<string, object>();
|
||||
|
||||
public LifetimeScope(InjectionContainer injectionContainer)
|
||||
internal LifetimeScope(InjectionContainer injectionContainer)
|
||||
{
|
||||
this.injectionContainer = injectionContainer;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Resolve{T}"/>
|
||||
public T Resolve<T>()
|
||||
{
|
||||
return (T)Resolve(typeof(T));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Resolve(Type)"/>
|
||||
public object Resolve(Type type)
|
||||
{
|
||||
return injectionContainer.InternalResolve(type, this);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public object Invoke<TInstance>(TInstance instance, Func<TInstance, Delegate> method)
|
||||
{
|
||||
return injectionContainer.InternalInvoke(instance, method, this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes all disposable scoped services
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (object? service in Services.Values)
|
||||
|
||||
@@ -2,78 +2,96 @@
|
||||
|
||||
namespace DynamicInjector
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="IContainer"/>
|
||||
/// </summary>
|
||||
public static class MethodInjectionContainerExtensions
|
||||
{
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static void Invoke<T>(this IContainer injectionContainer, Func<T, Delegate> method)
|
||||
{
|
||||
injectionContainer.Invoke(injectionContainer.Resolve<T>(), method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult>(this IContainer injectionContainer, T instance, Func<T, Func<TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(instance, method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult, T1>(this IContainer injectionContainer, T instance, Func<T, Func<T1, TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(instance, method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult, T1, T2>(this IContainer injectionContainer, T instance, Func<T, Func<T1, T2, TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(instance, method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult, T1, T2, T3>(this IContainer injectionContainer, T instance, Func<T, Func<T1, T2, T3, TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(instance, method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult, T1, T2, T3, T4>(this IContainer injectionContainer, T instance, Func<T, Func<T1, T2, T3, T4, TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(instance, method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult, T1, T2, T3, T4, T5>(this IContainer injectionContainer, T instance, Func<T, Func<T1, T2, T3, T4, T5, TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(instance, method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult, T1, T2, T3, T4, T5, T6>(this IContainer injectionContainer, T instance, Func<T, Func<T1, T2, T3, T4, T5, T6, TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(instance, method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult>(this IContainer injectionContainer, Func<T, Func<TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(injectionContainer.Resolve<T>(), method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult, T1>(this IContainer injectionContainer, Func<T, Func<T1, TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(injectionContainer.Resolve<T>(), method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult, T1, T2>(this IContainer injectionContainer, Func<T, Func<T1, T2, TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(injectionContainer.Resolve<T>(), method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult, T1, T2, T3>(this IContainer injectionContainer, Func<T, Func<T1, T2, T3, TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(injectionContainer.Resolve<T>(), method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult, T1, T2, T3, T4>(this IContainer injectionContainer, Func<T, Func<T1, T2, T3, T4, TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(injectionContainer.Resolve<T>(), method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult, T1, T2, T3, T4, T5>(this IContainer injectionContainer, Func<T, Func<T1, T2, T3, T4, T5, TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(injectionContainer.Resolve<T>(), method);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
|
||||
public static TResult Invoke<T, TResult, T1, T2, T3, T4, T5, T6>(this IContainer injectionContainer, Func<T, Func<T1, T2, T3, T4, T5, T6, TResult>> method)
|
||||
{
|
||||
return (TResult)injectionContainer.Invoke(injectionContainer.Resolve<T>(), method);
|
||||
|
||||
Reference in New Issue
Block a user