- 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);
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();
+10 -1
View File
@@ -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>
+20
View File
@@ -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>();
}
}
+3
View File
@@ -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
{
+53 -2
View File
@@ -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}\"!");
}
}
+11 -2
View File
@@ -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);