- Add documentation

This commit is contained in:
Stone_Red
2021-12-19 23:03:19 +01:00
parent 2f70f5cda6
commit 57a4249a2e
7 changed files with 117 additions and 7 deletions
+2 -2
View File
@@ -17,8 +17,8 @@ internal class Prgramm
int res = scope.Invoke<TestClass, int, SecondTestService>(testClass, (i) => i.SecondTest); int res = scope.Invoke<TestClass, int, SecondTestService>(testClass, (i) => i.SecondTest);
Console.WriteLine(res); Console.WriteLine(res);
scope.Invoke<TestClass>(testClass, (i) => i.SecondTest); scope.Invoke(testClass, (i) => i.SecondTest);
scope.Invoke<TestClass>(testClass, (i) => i.SecondTest); scope.Invoke(testClass, (i) => i.SecondTest);
} }
Console.WriteLine(); Console.WriteLine();
+10 -1
View File
@@ -1,8 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework> <TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Vsxmd" Version="1.4.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> </Project>
+20
View File
@@ -2,12 +2,32 @@
namespace DynamicInjector namespace DynamicInjector
{ {
/// <summary>
/// Container
/// </summary>
public interface IContainer 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); 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); 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>(); public T Resolve<T>();
} }
} }
+3
View File
@@ -2,6 +2,9 @@
namespace DynamicInjector 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)] [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public class InjectAttribute : Attribute public class InjectAttribute : Attribute
{ {
+53 -2
View File
@@ -4,22 +4,44 @@ using System.Reflection;
namespace DynamicInjector namespace DynamicInjector
{ {
/// <summary>
/// Container which handles all registered services
/// </summary>
public class InjectionContainer : IContainer public class InjectionContainer : IContainer
{ {
private readonly Dictionary<string, object> globalServices = new Dictionary<string, object>(); 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> localServices = new Dictionary<string, Type>();
private readonly Dictionary<string, Type> scopedServices = 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) public void RegisterGlobal<TService>(string? name = null)
{ {
globalServices.Add(name ?? typeof(TService).FullName, Resolve<TService>()!); 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 public void RegisterGlobal<TService, TImplementation>(string? name = null) where TImplementation : TService
{ {
globalServices.Add(name ?? typeof(TService).FullName, Resolve<TImplementation>()!); 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 public void RegisterGlobal<TService, TImplementation>(TImplementation implementation, string? name = null) where TImplementation : TService
{ {
if (implementation is null) if (implementation is null)
@@ -30,36 +52,64 @@ namespace DynamicInjector
globalServices.Add(name ?? typeof(TService).FullName, implementation); 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) public void RegisterLocal<TService>(string? name = null)
{ {
localServices.Add(name ?? typeof(TService).FullName, typeof(TService)); 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 public void RegisterLocal<TService, TImplementation>(string? name = null) where TImplementation : TService
{ {
localServices.Add(name ?? typeof(TService).FullName, typeof(TImplementation)); 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) public void RegisterScoped<TService>(string? name = null)
{ {
scopedServices.Add(name ?? typeof(TService).FullName, typeof(TService)); 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 public void RegisterScoped<TService, TImplementation>(string? name = null) where TImplementation : TService
{ {
scopedServices.Add(name ?? typeof(TService).FullName, typeof(TImplementation)); scopedServices.Add(name ?? typeof(TService).FullName, typeof(TImplementation));
} }
/// <summary>
/// Begins a new scope
/// </summary>
/// <returns>A new scope</returns>
public LifetimeScope BeginScope() public LifetimeScope BeginScope()
{ {
return new LifetimeScope(this); return new LifetimeScope(this);
} }
/// <inheritdoc cref="IContainer.Resolve{T}"/>
public T Resolve<T>() public T Resolve<T>()
{ {
return (T)Resolve(typeof(T)); return (T)Resolve(typeof(T));
} }
/// <inheritdoc cref="IContainer.Resolve(Type)"/>
public object Resolve(Type type) public object Resolve(Type type)
{ {
return InternalResolve(type, null); return InternalResolve(type, null);
@@ -76,7 +126,7 @@ namespace DynamicInjector
if (constructorInfos.Length > 1) 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]; ConstructorInfo constructorInfo = constructorInfos[0];
@@ -132,6 +182,7 @@ namespace DynamicInjector
return instance; return instance;
} }
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
public object Invoke<TInstance>(TInstance instance, Func<TInstance, Delegate> method) public object Invoke<TInstance>(TInstance instance, Func<TInstance, Delegate> method)
{ {
return InternalInvoke(instance, method, null); return InternalInvoke(instance, method, null);
@@ -162,7 +213,7 @@ namespace DynamicInjector
} }
else else
{ {
throw new InvalidOperationException($"Service \"{parameterInfo.ParameterType.FullName}\" not found!"); throw new InvalidOperationException($"Cannot find service \"{parameterInfo.ParameterType.FullName}\"!");
} }
} }
+11 -2
View File
@@ -3,32 +3,41 @@ using System.Collections.Generic;
namespace DynamicInjector namespace DynamicInjector
{ {
/// <summary>
/// A scope
/// </summary>
public class LifetimeScope : IContainer, IDisposable public class LifetimeScope : IContainer, IDisposable
{ {
private readonly InjectionContainer injectionContainer; 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; this.injectionContainer = injectionContainer;
} }
/// <inheritdoc cref="IContainer.Resolve{T}"/>
public T Resolve<T>() public T Resolve<T>()
{ {
return (T)Resolve(typeof(T)); return (T)Resolve(typeof(T));
} }
/// <inheritdoc cref="IContainer.Resolve(Type)"/>
public object Resolve(Type type) public object Resolve(Type type)
{ {
return injectionContainer.InternalResolve(type, this); return injectionContainer.InternalResolve(type, this);
} }
/// <inheritdoc cref="IContainer.Invoke{TInstance}(TInstance, Func{TInstance, Delegate})"/>
public object Invoke<TInstance>(TInstance instance, Func<TInstance, Delegate> method) public object Invoke<TInstance>(TInstance instance, Func<TInstance, Delegate> method)
{ {
return injectionContainer.InternalInvoke(instance, method, this); return injectionContainer.InternalInvoke(instance, method, this);
} }
/// <summary>
/// Disposes all disposable scoped services
/// </summary>
public void Dispose() public void Dispose()
{ {
foreach (object? service in Services.Values) foreach (object? service in Services.Values)
@@ -2,78 +2,96 @@
namespace DynamicInjector namespace DynamicInjector
{ {
/// <summary>
/// Extension methods for <see cref="IContainer"/>
/// </summary>
public static class MethodInjectionContainerExtensions 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) public static void Invoke<T>(this IContainer injectionContainer, Func<T, Delegate> method)
{ {
injectionContainer.Invoke(injectionContainer.Resolve<T>(), 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) public static TResult Invoke<T, TResult>(this IContainer injectionContainer, T instance, Func<T, Func<TResult>> method)
{ {
return (TResult)injectionContainer.Invoke(instance, 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) public static TResult Invoke<T, TResult, T1>(this IContainer injectionContainer, T instance, Func<T, Func<T1, TResult>> method)
{ {
return (TResult)injectionContainer.Invoke(instance, 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) 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); 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) 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); 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) 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); 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) 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); 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) 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); 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) public static TResult Invoke<T, TResult>(this IContainer injectionContainer, Func<T, Func<TResult>> method)
{ {
return (TResult)injectionContainer.Invoke(injectionContainer.Resolve<T>(), 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) public static TResult Invoke<T, TResult, T1>(this IContainer injectionContainer, Func<T, Func<T1, TResult>> method)
{ {
return (TResult)injectionContainer.Invoke(injectionContainer.Resolve<T>(), 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) 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); 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) 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); 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) 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); 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) 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); 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) 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); return (TResult)injectionContainer.Invoke(injectionContainer.Resolve<T>(), method);