diff --git a/DynamicInjector-Test/Program.cs b/DynamicInjector-Test/Program.cs index c307a9d..ee70d24 100644 --- a/DynamicInjector-Test/Program.cs +++ b/DynamicInjector-Test/Program.cs @@ -17,8 +17,8 @@ internal class Prgramm int res = scope.Invoke(testClass, (i) => i.SecondTest); Console.WriteLine(res); - scope.Invoke(testClass, (i) => i.SecondTest); - scope.Invoke(testClass, (i) => i.SecondTest); + scope.Invoke(testClass, (i) => i.SecondTest); + scope.Invoke(testClass, (i) => i.SecondTest); } Console.WriteLine(); diff --git a/DynamicInjector/DynamicInjector.csproj b/DynamicInjector/DynamicInjector.csproj index 8ef8970..db98969 100644 --- a/DynamicInjector/DynamicInjector.csproj +++ b/DynamicInjector/DynamicInjector.csproj @@ -1,8 +1,17 @@ - + netstandard2.1 enable + True + True + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + diff --git a/DynamicInjector/IContainer.cs b/DynamicInjector/IContainer.cs index 4653a2c..dc3c301 100644 --- a/DynamicInjector/IContainer.cs +++ b/DynamicInjector/IContainer.cs @@ -2,12 +2,32 @@ namespace DynamicInjector { + /// + /// Container + /// public interface IContainer { + /// + /// Invoke method in class and resolve services + /// + /// + /// + /// + /// The result of the specified method public object Invoke(TInstance instance, Func method); + /// + /// Returns an instance of a class with all resolved services from the service container + /// + /// + /// A class with all resolved services public object Resolve(Type type); + /// + /// Returns an instance of a class with all resolved services + /// + /// + /// A class with all resolved services public T Resolve(); } } \ No newline at end of file diff --git a/DynamicInjector/InjectAttribute.cs b/DynamicInjector/InjectAttribute.cs index 2bba137..7b7b247 100644 --- a/DynamicInjector/InjectAttribute.cs +++ b/DynamicInjector/InjectAttribute.cs @@ -2,6 +2,9 @@ namespace DynamicInjector { + /// + /// Indicates that the associated property should have a value injected from the service container during initialization. + /// [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] public class InjectAttribute : Attribute { diff --git a/DynamicInjector/InjectionContainer.cs b/DynamicInjector/InjectionContainer.cs index 7ca5543..0cc0a98 100644 --- a/DynamicInjector/InjectionContainer.cs +++ b/DynamicInjector/InjectionContainer.cs @@ -4,22 +4,44 @@ using System.Reflection; namespace DynamicInjector { + /// + /// Container which handles all registered services + /// public class InjectionContainer : IContainer { private readonly Dictionary globalServices = new Dictionary(); private readonly Dictionary localServices = new Dictionary(); private readonly Dictionary scopedServices = new Dictionary(); + /// + /// Registers a global service + /// + /// + /// public void RegisterGlobal(string? name = null) { globalServices.Add(name ?? typeof(TService).FullName, Resolve()!); } + /// + /// Registers a global service + /// + /// + /// + /// public void RegisterGlobal(string? name = null) where TImplementation : TService { globalServices.Add(name ?? typeof(TService).FullName, Resolve()!); } + /// + /// Registers a global service + /// + /// + /// + /// + /// + /// public void RegisterGlobal(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); } + /// + /// Registers a local service + /// + /// + /// public void RegisterLocal(string? name = null) { localServices.Add(name ?? typeof(TService).FullName, typeof(TService)); } + /// + /// Registers a local service + /// + /// + /// + /// public void RegisterLocal(string? name = null) where TImplementation : TService { localServices.Add(name ?? typeof(TService).FullName, typeof(TImplementation)); } + /// + /// Registers a scoped service + /// + /// + /// public void RegisterScoped(string? name = null) { scopedServices.Add(name ?? typeof(TService).FullName, typeof(TService)); } + /// + /// Registers a scoped service + /// + /// + /// + /// public void RegisterScoped(string? name = null) where TImplementation : TService { scopedServices.Add(name ?? typeof(TService).FullName, typeof(TImplementation)); } + /// + /// Begins a new scope + /// + /// A new scope public LifetimeScope BeginScope() { return new LifetimeScope(this); } + /// public T Resolve() { return (T)Resolve(typeof(T)); } + /// 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; } + /// public object Invoke(TInstance instance, Func 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}\"!"); } } diff --git a/DynamicInjector/LifetimeScope.cs b/DynamicInjector/LifetimeScope.cs index 18fce41..36c6ff6 100644 --- a/DynamicInjector/LifetimeScope.cs +++ b/DynamicInjector/LifetimeScope.cs @@ -3,32 +3,41 @@ using System.Collections.Generic; namespace DynamicInjector { + /// + /// A scope + /// public class LifetimeScope : IContainer, IDisposable { private readonly InjectionContainer injectionContainer; - public Dictionary Services { get; } = new Dictionary(); + internal Dictionary Services { get; } = new Dictionary(); - public LifetimeScope(InjectionContainer injectionContainer) + internal LifetimeScope(InjectionContainer injectionContainer) { this.injectionContainer = injectionContainer; } + /// public T Resolve() { return (T)Resolve(typeof(T)); } + /// public object Resolve(Type type) { return injectionContainer.InternalResolve(type, this); } + /// public object Invoke(TInstance instance, Func method) { return injectionContainer.InternalInvoke(instance, method, this); } + /// + /// Disposes all disposable scoped services + /// public void Dispose() { foreach (object? service in Services.Values) diff --git a/DynamicInjector/MethodInjectionContainerExtensions.cs b/DynamicInjector/MethodInjectionContainerExtensions.cs index 0bb23de..4a930cc 100644 --- a/DynamicInjector/MethodInjectionContainerExtensions.cs +++ b/DynamicInjector/MethodInjectionContainerExtensions.cs @@ -2,78 +2,96 @@ namespace DynamicInjector { + /// + /// Extension methods for + /// public static class MethodInjectionContainerExtensions { + /// public static void Invoke(this IContainer injectionContainer, Func method) { injectionContainer.Invoke(injectionContainer.Resolve(), method); } + /// public static TResult Invoke(this IContainer injectionContainer, T instance, Func> method) { return (TResult)injectionContainer.Invoke(instance, method); } + /// public static TResult Invoke(this IContainer injectionContainer, T instance, Func> method) { return (TResult)injectionContainer.Invoke(instance, method); } + /// public static TResult Invoke(this IContainer injectionContainer, T instance, Func> method) { return (TResult)injectionContainer.Invoke(instance, method); } + /// public static TResult Invoke(this IContainer injectionContainer, T instance, Func> method) { return (TResult)injectionContainer.Invoke(instance, method); } + /// public static TResult Invoke(this IContainer injectionContainer, T instance, Func> method) { return (TResult)injectionContainer.Invoke(instance, method); } + /// public static TResult Invoke(this IContainer injectionContainer, T instance, Func> method) { return (TResult)injectionContainer.Invoke(instance, method); } + /// public static TResult Invoke(this IContainer injectionContainer, T instance, Func> method) { return (TResult)injectionContainer.Invoke(instance, method); } + /// public static TResult Invoke(this IContainer injectionContainer, Func> method) { return (TResult)injectionContainer.Invoke(injectionContainer.Resolve(), method); } + /// public static TResult Invoke(this IContainer injectionContainer, Func> method) { return (TResult)injectionContainer.Invoke(injectionContainer.Resolve(), method); } + /// public static TResult Invoke(this IContainer injectionContainer, Func> method) { return (TResult)injectionContainer.Invoke(injectionContainer.Resolve(), method); } + /// public static TResult Invoke(this IContainer injectionContainer, Func> method) { return (TResult)injectionContainer.Invoke(injectionContainer.Resolve(), method); } + /// public static TResult Invoke(this IContainer injectionContainer, Func> method) { return (TResult)injectionContainer.Invoke(injectionContainer.Resolve(), method); } + /// public static TResult Invoke(this IContainer injectionContainer, Func> method) { return (TResult)injectionContainer.Invoke(injectionContainer.Resolve(), method); } + /// public static TResult Invoke(this IContainer injectionContainer, Func> method) { return (TResult)injectionContainer.Invoke(injectionContainer.Resolve(), method);