From 6f99cc8dd005229767a627336ec235a9ddf3218b Mon Sep 17 00:00:00 2001 From: JacopoWolf Date: Wed, 13 May 2020 13:12:38 +0200 Subject: [PATCH 01/13] Total refractoring - created StackInjector.Core namespace - core shared logic is now a separated object - implemented default behaviuours in StackWrapperBase - moved StackWrapper implementations in source folder --- .../{StackWrapper => }/AsyncStackWrapper.cs | 18 ++-- .../AsyncStackWrapper.logic.cs | 13 +-- StackInjector/Core/StackWrapperBase.cs | 65 +++++++++++++ StackInjector/Core/WrapperCore.cs | 34 +++++++ .../WrapperCore.injection.cs} | 7 +- .../WrapperCore.instantiation.cs} | 22 +++-- .../WrapperCore.logic.cs} | 26 +++--- .../WrapperCore.reflection.cs} | 18 ++-- .../WrapperCore.versioning.cs} | 6 +- StackInjector/IStackWrapperStructure.cs | 6 +- StackInjector/Injector.cs | 67 +++++-------- .../Settings/StackWrapperSettings.cs | 15 ++- StackInjector/StackWrapper.cs | 56 +++++++++++ StackInjector/StackWrapper/StackWrapper.cs | 93 ------------------- .../Services/TestGenerator.cs | 3 +- tests/StackInjector.TEST.Async/TestProgram.cs | 4 - .../TestProgram.cs | 22 +++-- 17 files changed, 258 insertions(+), 217 deletions(-) rename StackInjector/{StackWrapper => }/AsyncStackWrapper.cs (75%) rename StackInjector/{StackWrapper => }/AsyncStackWrapper.logic.cs (85%) create mode 100644 StackInjector/Core/StackWrapperBase.cs create mode 100644 StackInjector/Core/WrapperCore.cs rename StackInjector/{StackWrapper/StackWrapper.injection.cs => Core/WrapperCore.injection.cs} (94%) rename StackInjector/{StackWrapper/StackWrapper.instantiation.cs => Core/WrapperCore.instantiation.cs} (74%) rename StackInjector/{StackWrapper/StackWrapper.logic.cs => Core/WrapperCore.logic.cs} (56%) rename StackInjector/{StackWrapper/StackWrapper.reflection.cs => Core/WrapperCore.reflection.cs} (82%) rename StackInjector/{StackWrapper/StackWrapper.versioning.cs => Core/WrapperCore.versioning.cs} (92%) create mode 100644 StackInjector/StackWrapper.cs delete mode 100644 StackInjector/StackWrapper/StackWrapper.cs diff --git a/StackInjector/StackWrapper/AsyncStackWrapper.cs b/StackInjector/AsyncStackWrapper.cs similarity index 75% rename from StackInjector/StackWrapper/AsyncStackWrapper.cs rename to StackInjector/AsyncStackWrapper.cs index aba3a3b..16914ee 100644 --- a/StackInjector/StackWrapper/AsyncStackWrapper.cs +++ b/StackInjector/AsyncStackWrapper.cs @@ -3,12 +3,13 @@ using System.Threading; using System.Threading.Tasks; using StackInjector.Attributes; +using StackInjector.Core; using StackInjector.Settings; namespace StackInjector { [Service(DoNotServeMembers = true, Version = 2.0)] - internal partial class AsyncStackWrapper : StackWrapper, IAsyncStackWrapper + internal partial class AsyncStackWrapper : StackWrapperBase, IAsyncStackWrapper { // used to cancel everything private readonly CancellationTokenSource cancelPendingTasksSource = new CancellationTokenSource(); @@ -30,10 +31,10 @@ internal partial class AsyncStackWrapper : StackWrapper, IAsyncStackWrapper /// /// create a new AsyncStackWrapper /// - /// - internal AsyncStackWrapper ( StackWrapperSettings settings ) : base(settings) + internal AsyncStackWrapper ( WrapperCore core ) : base(core,typeof(AsyncStackWrapper)) { - // in case the list is empty, release the empty event listener. + + // register an event that in case the list is empty, release the empty event listener. this.cancelPendingTasksSource.Token.Register(this.ReleaseListAwaiter); } @@ -50,8 +51,8 @@ private void ReleaseListAwaiter () public override string ToString () => - $"AsyncStackWrapper{{ {this.ServicesWithInstances.GetAllTypes().Count()} registered types; " + - $"entry point: {this.EntryPoint.Name}; canceled: {this.cancelPendingTasksSource.IsCancellationRequested} }}"; + $"AsyncStackWrapper{{ {this.Core.instances.GetAllTypes().Count()} registered types; " + + $"entry point: {this.Core.entryPoint.Name}; canceled: {this.cancelPendingTasksSource.IsCancellationRequested} }}"; @@ -59,7 +60,7 @@ public override string ToString () private bool disposedValue = false; - public new void Dispose () + public override void Dispose () { if( !this.disposedValue ) { @@ -77,8 +78,7 @@ public override string ToString () this.tasks = null; // clean instantiated objects - this.RemoveInstancesDiff(); - this.instancesDiff.Clear(); + this.Core.RemoveInstancesDiff(); this.disposedValue = true; diff --git a/StackInjector/StackWrapper/AsyncStackWrapper.logic.cs b/StackInjector/AsyncStackWrapper.logic.cs similarity index 85% rename from StackInjector/StackWrapper/AsyncStackWrapper.logic.cs rename to StackInjector/AsyncStackWrapper.logic.cs index 4ce4ecd..f7dae2c 100644 --- a/StackInjector/StackWrapper/AsyncStackWrapper.logic.cs +++ b/StackInjector/AsyncStackWrapper.logic.cs @@ -64,17 +64,8 @@ public bool AnyTaskLeft () /// /// internal IAsyncStackEntryPoint GetAsyncEntryPoint () - { - return - (IAsyncStackEntryPoint) - this - .ServicesWithInstances - .OfType - ( - this.ClassOrFromInterface(this.EntryPoint) - ) - .First(); - } + => + this.Core.GetEntryPoint(); } } diff --git a/StackInjector/Core/StackWrapperBase.cs b/StackInjector/Core/StackWrapperBase.cs new file mode 100644 index 0000000..4fb5685 --- /dev/null +++ b/StackInjector/Core/StackWrapperBase.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Text; +using StackInjector.Behaviours; +using StackInjector.Core; +using StackInjector.Settings; + +namespace StackInjector.Core +{ + internal abstract class StackWrapperBase : IStackWrapperStructure + { + public ref readonly StackWrapperSettings Settings + => ref this.Core.settings; + + + private protected readonly WrapperCore Core; + + + public StackWrapperBase ( WrapperCore core, Type toRegister ) + { + this.Core = core; + + // setting for referencing the calling wrapper as a service + if( this.Core.settings.registerSelf ) + this.Core.instances.AddInstance( toRegister , this ); + } + + + public IStackWrapper FromStructure ( StackWrapperSettings overrideSettings = null ) where T : IStackEntryPoint + { + + var clonedCore = new WrapperCore( overrideSettings ?? this.Core.settings ) + { + entryPoint = typeof(T), + instances = this.Core.instances + }; + + var wrapper = new StackWrapper( clonedCore ); + + wrapper.Core.ServeAll(); + + return wrapper; + } + + public IAsyncStackWrapper AsyncFromStructure ( StackWrapperSettings overrideSettings = null ) where T : IAsyncStackEntryPoint + { + var clonedCore = new WrapperCore( overrideSettings ?? this.Core.settings ) + { + entryPoint = typeof(T), + instances = this.Core.instances + }; + + var wrapper = new AsyncStackWrapper( clonedCore ); + + clonedCore.ServeAll(); + + return wrapper; + } + + + + + public abstract void Dispose (); + } +} diff --git a/StackInjector/Core/WrapperCore.cs b/StackInjector/Core/WrapperCore.cs new file mode 100644 index 0000000..957d9db --- /dev/null +++ b/StackInjector/Core/WrapperCore.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text; +using StackInjector.Behaviours; +using StackInjector.Settings; + +namespace StackInjector.Core +{ + internal partial class WrapperCore + { + // entry point object of this core + internal Type entryPoint; + + // manage settings + internal StackWrapperSettings settings; + + // holds instances + internal IInstancesHolder instances; + + // tracks instantiated objects + internal readonly List instancesDiff; + + + internal WrapperCore ( StackWrapperSettings settings ) + { + this.settings = settings; + + this.instances = new SingleInstanceHolder(); + + if( this.settings.trackInstancesDiff ) + this.instancesDiff = new List(); + } + } +} diff --git a/StackInjector/StackWrapper/StackWrapper.injection.cs b/StackInjector/Core/WrapperCore.injection.cs similarity index 94% rename from StackInjector/StackWrapper/StackWrapper.injection.cs rename to StackInjector/Core/WrapperCore.injection.cs index c8d8b47..3bf6199 100644 --- a/StackInjector/StackWrapper/StackWrapper.injection.cs +++ b/StackInjector/Core/WrapperCore.injection.cs @@ -3,10 +3,13 @@ using System.Reflection; using StackInjector.Attributes; -namespace StackInjector +namespace StackInjector.Core { - internal partial class StackWrapper + internal partial class WrapperCore { + //! maintainability of 52/100 + //todo simplify this method + /// /// Injects services into the specified instance, instantiating them on necessity. /// diff --git a/StackInjector/StackWrapper/StackWrapper.instantiation.cs b/StackInjector/Core/WrapperCore.instantiation.cs similarity index 74% rename from StackInjector/StackWrapper/StackWrapper.instantiation.cs rename to StackInjector/Core/WrapperCore.instantiation.cs index 9c2d375..96e1be8 100644 --- a/StackInjector/StackWrapper/StackWrapper.instantiation.cs +++ b/StackInjector/Core/WrapperCore.instantiation.cs @@ -4,9 +4,9 @@ using StackInjector.Attributes; using StackInjector.Exceptions; -namespace StackInjector +namespace StackInjector.Core { - internal partial class StackWrapper + internal partial class WrapperCore { /// /// Instantiates the specified [Served] type @@ -20,10 +20,10 @@ internal object InstantiateService ( Type type ) //todo check for default constructor. If not present, throw custom exception var instance = Activator.CreateInstance( type ); - this.ServicesWithInstances.AddInstance(type, instance); + this.instances.AddInstance(type, instance); // if true, track instantiated objects - if( this.Settings.trackInstancesDiff ) + if( this.settings.trackInstancesDiff ) this.instancesDiff.Add(instance); return instance; @@ -35,11 +35,11 @@ internal object OfTypeOrInstantiate ( Type type ) if( type.GetCustomAttribute() == null ) throw new NotAServiceException(type, $"The type {type.FullName} is not annotated with [Service]"); - if( !this.ServicesWithInstances.ContainsType(type) ) + if( !this.instances.ContainsType(type) ) throw new ClassNotFoundException(type, $"The type {type.FullName} is not in a registred assembly!"); - var instanceOfType = this.ServicesWithInstances.OfType(type).First(); + var instanceOfType = this.instances.OfType(type).First(); if( instanceOfType is null ) return this.InstantiateService(type); @@ -51,20 +51,22 @@ internal object OfTypeOrInstantiate ( Type type ) /// /// removes instances of the tracked instantiated types and call their Dispose method /// - protected void RemoveInstancesDiff () + internal void RemoveInstancesDiff () { - if( !this.Settings.trackInstancesDiff ) + if( !this.settings.trackInstancesDiff ) return; foreach( var instance in this.instancesDiff ) { - this.ServicesWithInstances.RemoveInstance(instance.GetType(), instance); + this.instances.RemoveInstance(instance.GetType(), instance); // if the relative setting is true, check if the instance implements IDisposable and call it - if( this.Settings.callDisposeOnInstanceDiff && instance is IDisposable disposable ) + if( this.settings.callDisposeOnInstanceDiff && instance is IDisposable disposable ) disposable.Dispose(); } + this.instancesDiff.Clear(); + } } diff --git a/StackInjector/StackWrapper/StackWrapper.logic.cs b/StackInjector/Core/WrapperCore.logic.cs similarity index 56% rename from StackInjector/StackWrapper/StackWrapper.logic.cs rename to StackInjector/Core/WrapperCore.logic.cs index 421531a..710d76e 100644 --- a/StackInjector/StackWrapper/StackWrapper.logic.cs +++ b/StackInjector/Core/WrapperCore.logic.cs @@ -1,24 +1,25 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; -namespace StackInjector +namespace StackInjector.Core { - internal partial class StackWrapper + internal partial class WrapperCore { - internal void ServeAll () + internal void ServeAll ( ) { - // setting for referencing this object from instances inside - if( this.Settings.registerSelf ) - this.ServicesWithInstances.AddInstance(this.GetType(), this); + ////// setting for referencing this object from instances inside + ////if( this.settings.registerSelf ) + //// this.instances.AddInstance(this.GetType(), this); var toInject = new Queue(); // instantiates and enqueues the EntryPoint toInject.Enqueue ( - this.InstantiateService(this.EntryPoint) + this.InstantiateService(this.entryPoint) ); // enqueuing loop @@ -37,15 +38,14 @@ internal void ServeAll () /// retrieves the entry point of the specified type /// /// - internal IStackEntryPoint GetStackEntryPoint () + internal T GetEntryPoint () { return - (IStackEntryPoint) - this - .ServicesWithInstances + (T)this + .instances .OfType ( - this.ClassOrFromInterface(this.EntryPoint) + this.ClassOrFromInterface(this.entryPoint) ) .First(); } diff --git a/StackInjector/StackWrapper/StackWrapper.reflection.cs b/StackInjector/Core/WrapperCore.reflection.cs similarity index 82% rename from StackInjector/StackWrapper/StackWrapper.reflection.cs rename to StackInjector/Core/WrapperCore.reflection.cs index 466c313..aca2438 100644 --- a/StackInjector/StackWrapper/StackWrapper.reflection.cs +++ b/StackInjector/Core/WrapperCore.reflection.cs @@ -4,9 +4,9 @@ using StackInjector.Attributes; using StackInjector.Exceptions; -namespace StackInjector +namespace StackInjector.Core { - internal partial class StackWrapper + internal partial class WrapperCore { /// /// Returns type if it's a [Service] class, @@ -24,9 +24,9 @@ internal Type ClassOrFromInterface ( Type type, ServedAttribute servedAttribute { var v = servedAttribute?.TargetVersion ?? 0.0; - var t = ( this.Settings.overrideTargetingMethod ) - ? this.Settings.targetingMethod - : servedAttribute?.TargetingMethod ?? this.Settings.targetingMethod; + var t = ( this.settings.overrideTargetingMethod ) + ? this.settings.targetingMethod + : servedAttribute?.TargetingMethod ?? this.settings.targetingMethod; return this.Version(type, v, t); @@ -49,13 +49,13 @@ internal Type ClassOrFromInterface ( Type type, ServedAttribute servedAttribute /// internal void ReadAssemblies () { - if( this.Settings.registerEntryPointAssembly ) - this.Settings.registredAssemblies.Add(this.EntryPoint.Assembly); + if( this.settings.registerEntryPointAssembly ) + this.settings.registredAssemblies.Add(this.entryPoint.Assembly); foreach ( var t in this - .Settings + .settings .registredAssemblies .SelectMany ( @@ -67,7 +67,7 @@ var t in this ) ) { - this.ServicesWithInstances.AddType(t); + this.instances.AddType(t); } } diff --git a/StackInjector/StackWrapper/StackWrapper.versioning.cs b/StackInjector/Core/WrapperCore.versioning.cs similarity index 92% rename from StackInjector/StackWrapper/StackWrapper.versioning.cs rename to StackInjector/Core/WrapperCore.versioning.cs index f96dda7..6e320f6 100644 --- a/StackInjector/StackWrapper/StackWrapper.versioning.cs +++ b/StackInjector/Core/WrapperCore.versioning.cs @@ -4,9 +4,9 @@ using StackInjector.Attributes; using StackInjector.Settings; -namespace StackInjector +namespace StackInjector.Core { - internal partial class StackWrapper + internal partial class WrapperCore { internal Type Version @@ -16,7 +16,7 @@ internal Type Version ServedVersionTargetingMethod method ) { - var candidateTypes = this.ServicesWithInstances.TypesAssignableFrom(targetType); + var candidateTypes = this.instances.TypesAssignableFrom(targetType); return method switch { diff --git a/StackInjector/IStackWrapperStructure.cs b/StackInjector/IStackWrapperStructure.cs index 15217a3..28e4fe2 100644 --- a/StackInjector/IStackWrapperStructure.cs +++ b/StackInjector/IStackWrapperStructure.cs @@ -1,4 +1,5 @@ using System; +using StackInjector.Core; using StackInjector.Settings; namespace StackInjector @@ -13,7 +14,10 @@ public interface IStackWrapperStructure : IDisposable /// /// the settings of this stackwrapper /// - StackWrapperSettings Settings { get; } + ref readonly StackWrapperSettings Settings { get; } + + + //todo modify those signatures for generics. Might help. /// /// Copy the structure of this existing wrapper and initialize a new one. diff --git a/StackInjector/Injector.cs b/StackInjector/Injector.cs index 19e63b0..c175f87 100644 --- a/StackInjector/Injector.cs +++ b/StackInjector/Injector.cs @@ -1,4 +1,5 @@ using StackInjector.Behaviours; +using StackInjector.Core; using StackInjector.Exceptions; using StackInjector.Settings; @@ -24,39 +25,27 @@ public static class Injector /// /// /// - public static IStackWrapper From ( this StackWrapperSettings settings ) where T : IStackEntryPoint + public static IStackWrapper From ( StackWrapperSettings settings = null ) where T : IStackEntryPoint { + if( settings == null ) + settings = StackWrapperSettings.Default; // create a new stackwrapper with the specified settings - var wrapper = new StackWrapper( settings ) + var core = new WrapperCore( settings ) { - EntryPoint = typeof(T), - ServicesWithInstances = new SingleInstanceHolder() + entryPoint = typeof(T) }; - wrapper.ReadAssemblies(); - wrapper.ServeAll(); + // putting this here allows for registration of this object when serving + var wrapper = new StackWrapper(core); + + core.ReadAssemblies(); + core.ServeAll(); return wrapper; } - /// - /// Create a new StackWrapper from the entry point - /// - /// The type of the entry point - /// The initialized StackWrapper - /// - /// - /// - public static IStackWrapper From () where T : IStackEntryPoint - { - // default configuration - return - StackWrapperSettings - .Default() - .From(); - } /// @@ -65,34 +54,26 @@ public static IStackWrapper From () where T : IStackEntryPoint /// /// /// - public static IAsyncStackWrapper AsyncFrom ( this StackWrapperSettings settings ) where T : IAsyncStackEntryPoint + public static IAsyncStackWrapper AsyncFrom ( StackWrapperSettings settings = null ) where T : IAsyncStackEntryPoint { + if( settings == null ) + { + settings = StackWrapperSettings.Default; + } + // create a new async stack wrapper - var wrapper = new AsyncStackWrapper( settings ) + var core = new WrapperCore( settings ) { - EntryPoint = typeof(T), - ServicesWithInstances = new SingleInstanceHolder() + entryPoint = typeof(T), + instances = new SingleInstanceHolder() }; - wrapper.ReadAssemblies(); - wrapper.ServeAll(); - - return wrapper; - } + var wrapper = new AsyncStackWrapper(core); + core.ReadAssemblies(); + core.ServeAll(); - /// - /// Create a new asyncronous StackWrapper from the entry point - /// - /// - /// - public static IAsyncStackWrapper AsyncFrom () - where T : IAsyncStackEntryPoint - { - return - StackWrapperSettings - .Default() - .AsyncFrom(); + return wrapper; } diff --git a/StackInjector/Settings/StackWrapperSettings.cs b/StackInjector/Settings/StackWrapperSettings.cs index 3811295..d49c889 100644 --- a/StackInjector/Settings/StackWrapperSettings.cs +++ b/StackInjector/Settings/StackWrapperSettings.cs @@ -38,25 +38,24 @@ private StackWrapperSettings () { } /// High chance a NullReference might be thrown if not treated correctly. /// /// empty settings - public static StackWrapperSettings Empty () - { - return new StackWrapperSettings(); - } + public static StackWrapperSettings Empty + => + new StackWrapperSettings(); + /// /// Creates a new StackWrapperSettings with default parameters. /// See what those are at the Wiki page /// /// the default settings - public static StackWrapperSettings Default () - { - return + public static StackWrapperSettings Default + => new StackWrapperSettings() .RegisterEntryAssembly() .RegisterWrapperAsService() .TrackInstantiationDiff( false ) .VersioningMethod(ServedVersionTargetingMethod.None, @override: false); - } + //todo maybe add a DefaultInner for nested wrappers diff --git a/StackInjector/StackWrapper.cs b/StackInjector/StackWrapper.cs new file mode 100644 index 0000000..cdde2fc --- /dev/null +++ b/StackInjector/StackWrapper.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using StackInjector.Attributes; +using StackInjector.Behaviours; +using StackInjector.Core; +using StackInjector.Settings; + +namespace StackInjector +{ + [Service(Version = 1.0, DoNotServeMembers = true)] + internal class StackWrapper : StackWrapperBase, IStackWrapper + { + + + internal StackWrapper(WrapperCore core) : base(core,typeof(StackWrapper)) + { } + + + /// + public T Start () + => + (T)this.Core.GetEntryPoint().EntryPoint(); + + + /// + public object Start () + => + this.Core.GetEntryPoint().EntryPoint(); + + + + public override string ToString () + => + $"StackWrapper{{ {this.Core.instances.GetAllTypes().Count()} registered types; entry point: {this.Core.entryPoint.Name} }}"; + + + + + + + + private bool disposed = false; + + public override void Dispose () + { + if (!this.disposed) + { + this.Core.RemoveInstancesDiff(); + + this.disposed = true; + } + } + } +} \ No newline at end of file diff --git a/StackInjector/StackWrapper/StackWrapper.cs b/StackInjector/StackWrapper/StackWrapper.cs deleted file mode 100644 index 53ecc54..0000000 --- a/StackInjector/StackWrapper/StackWrapper.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using StackInjector.Attributes; -using StackInjector.Behaviours; -using StackInjector.Settings; - -namespace StackInjector -{ - [Service(ReuseInstance = true, Version = 1.0, DoNotServeMembers = true)] - internal partial class StackWrapper : IStackWrapper - { - - internal Type EntryPoint { get; set; } - - public StackWrapperSettings Settings { get; internal set; } - - - internal IInstancesHolder ServicesWithInstances { get; set; } - - private protected readonly List instancesDiff = new List(); - - - /// - /// internal constructor. - /// - internal StackWrapper ( StackWrapperSettings settings ) - => - this.Settings = settings; - - - - /// - public T Start () - => - (T)this.GetStackEntryPoint().EntryPoint(); - - - /// - public object Start () - => - this.GetStackEntryPoint().EntryPoint(); - - - - public override string ToString () - => - $"StackWrapper{{ {this.ServicesWithInstances.GetAllTypes().Count()} registered types; entry point: {this.EntryPoint.Name} }}"; - - - - public IStackWrapper FromStructure ( StackWrapperSettings overrideSettings = null ) where T : IStackEntryPoint - { - var clonedWrapper = new StackWrapper( overrideSettings ?? this.Settings ) - { - EntryPoint = typeof(T), - ServicesWithInstances = this.ServicesWithInstances - }; - - clonedWrapper.ServeAll(); - - return clonedWrapper; - } - - public IAsyncStackWrapper AsyncFromStructure ( StackWrapperSettings overrideSettings = null ) where T : IAsyncStackEntryPoint - { - var clonedWrapper = new AsyncStackWrapper( overrideSettings ?? this.Settings ) - { - EntryPoint = typeof(T), - ServicesWithInstances = this.ServicesWithInstances - }; - - clonedWrapper.ServeAll(); - - return clonedWrapper; - } - - - private bool disposed = false; - - public void Dispose () - { - if (!this.disposed) - { - // if any, remove tracked instances. - this.RemoveInstancesDiff(); - this.instancesDiff.Clear(); - - this.disposed = true; - } - } - } -} \ No newline at end of file diff --git a/tests/StackInjector.TEST.Async/Services/TestGenerator.cs b/tests/StackInjector.TEST.Async/Services/TestGenerator.cs index af1359e..43e2ee9 100644 --- a/tests/StackInjector.TEST.Async/Services/TestGenerator.cs +++ b/tests/StackInjector.TEST.Async/Services/TestGenerator.cs @@ -60,8 +60,9 @@ async Task> waitForRes () Console.Write($"{d}; "); Console.WriteLine(); - + elaborationWrapper.Dispose(); + Console.WriteLine(elaborationWrapper); return 0; diff --git a/tests/StackInjector.TEST.Async/TestProgram.cs b/tests/StackInjector.TEST.Async/TestProgram.cs index 74886b5..471be46 100644 --- a/tests/StackInjector.TEST.Async/TestProgram.cs +++ b/tests/StackInjector.TEST.Async/TestProgram.cs @@ -27,10 +27,8 @@ public async Task TestAsync () { asyncwrapper.Submit(item); - Thread.Sleep(10); // <<<----- I want to highlight this this is for asyncronous testing purposes // and it's the cause of the 100+ milliseconds of elaboration required for this test - } } ); @@ -47,8 +45,6 @@ public async Task TestAsync () } - - [Test] public void ServeAsync () { diff --git a/tests/StackInjector.TEST.Versioning/TestProgram.cs b/tests/StackInjector.TEST.Versioning/TestProgram.cs index 86ead91..6487da3 100644 --- a/tests/StackInjector.TEST.Versioning/TestProgram.cs +++ b/tests/StackInjector.TEST.Versioning/TestProgram.cs @@ -10,21 +10,23 @@ internal class TestProgram [Test] public void MinorVersioning() { - StackWrapperSettings - .Default() - .VersioningMethod( ServedVersionTargetingMethod.LatestMinor ) - .From() - .Start(); + var settings = + StackWrapperSettings + .Default + .VersioningMethod(ServedVersionTargetingMethod.LatestMinor); + + Injector.From( settings ).Start(); } [Test] public void MajorVersioning() { - StackWrapperSettings - .Default() - .VersioningMethod( ServedVersionTargetingMethod.LatestMajor ) - .From() - .Start(); + var settings = + StackWrapperSettings + .Default + .VersioningMethod(ServedVersionTargetingMethod.LatestMajor); + + Injector.From( settings ).Start(); } From a6a5b6b7504a32c23770e0d6b289fb3e31d53d00 Mon Sep 17 00:00:00 2001 From: JacopoWolf Date: Wed, 13 May 2020 17:11:00 +0200 Subject: [PATCH 02/13] created StackInjector.Wrappers namespace - moved all wrappers inside of it --- StackInjector/Core/StackWrapperBase.cs | 1 + StackInjector/Injector.cs | 1 + StackInjector/Settings/StackWrapperSettings.cs | 1 + StackInjector/{ => Wrappers}/AsyncStackWrapper.cs | 3 ++- StackInjector/{ => Wrappers}/AsyncStackWrapper.logic.cs | 7 ++++++- StackInjector/{ => Wrappers}/IAsyncStackEntryPoint.cs | 2 +- StackInjector/{ => Wrappers}/IAsyncStackWrapper.cs | 2 +- StackInjector/{ => Wrappers}/IStackEntryPoint.cs | 2 +- StackInjector/{ => Wrappers}/IStackWrapper.cs | 4 +++- StackInjector/{ => Wrappers}/IStackWrapperStructure.cs | 2 +- StackInjector/{ => Wrappers}/StackWrapper.cs | 8 ++++---- tests/StackInjector.TEST.Async/Services/PowElaborators.cs | 1 + tests/StackInjector.TEST.Async/Services/TestGenerator.cs | 1 + .../Services/BadThingsGenerators.cs | 1 + .../Services/ServiceCloningEntryPoint.cs | 1 + .../Services/ThingsGenerator.cs | 1 + .../StackInjector.TEST.Versioning/Services/EntryPoints.cs | 1 + 17 files changed, 28 insertions(+), 11 deletions(-) rename StackInjector/{ => Wrappers}/AsyncStackWrapper.cs (97%) rename StackInjector/{ => Wrappers}/AsyncStackWrapper.logic.cs (91%) rename StackInjector/{ => Wrappers}/IAsyncStackEntryPoint.cs (95%) rename StackInjector/{ => Wrappers}/IAsyncStackWrapper.cs (97%) rename StackInjector/{ => Wrappers}/IStackEntryPoint.cs (89%) rename StackInjector/{ => Wrappers}/IStackWrapper.cs (94%) rename StackInjector/{ => Wrappers}/IStackWrapperStructure.cs (97%) rename StackInjector/{ => Wrappers}/StackWrapper.cs (86%) diff --git a/StackInjector/Core/StackWrapperBase.cs b/StackInjector/Core/StackWrapperBase.cs index 4fb5685..0a43d26 100644 --- a/StackInjector/Core/StackWrapperBase.cs +++ b/StackInjector/Core/StackWrapperBase.cs @@ -4,6 +4,7 @@ using StackInjector.Behaviours; using StackInjector.Core; using StackInjector.Settings; +using StackInjector.Wrappers; namespace StackInjector.Core { diff --git a/StackInjector/Injector.cs b/StackInjector/Injector.cs index c175f87..c369169 100644 --- a/StackInjector/Injector.cs +++ b/StackInjector/Injector.cs @@ -2,6 +2,7 @@ using StackInjector.Core; using StackInjector.Exceptions; using StackInjector.Settings; +using StackInjector.Wrappers; namespace StackInjector { diff --git a/StackInjector/Settings/StackWrapperSettings.cs b/StackInjector/Settings/StackWrapperSettings.cs index d49c889..d79f44d 100644 --- a/StackInjector/Settings/StackWrapperSettings.cs +++ b/StackInjector/Settings/StackWrapperSettings.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using StackInjector.Wrappers; namespace StackInjector.Settings { diff --git a/StackInjector/AsyncStackWrapper.cs b/StackInjector/Wrappers/AsyncStackWrapper.cs similarity index 97% rename from StackInjector/AsyncStackWrapper.cs rename to StackInjector/Wrappers/AsyncStackWrapper.cs index 16914ee..9dec059 100644 --- a/StackInjector/AsyncStackWrapper.cs +++ b/StackInjector/Wrappers/AsyncStackWrapper.cs @@ -5,8 +5,9 @@ using StackInjector.Attributes; using StackInjector.Core; using StackInjector.Settings; +using StackInjector.Wrappers; -namespace StackInjector +namespace StackInjector.Wrappers { [Service(DoNotServeMembers = true, Version = 2.0)] internal partial class AsyncStackWrapper : StackWrapperBase, IAsyncStackWrapper diff --git a/StackInjector/AsyncStackWrapper.logic.cs b/StackInjector/Wrappers/AsyncStackWrapper.logic.cs similarity index 91% rename from StackInjector/AsyncStackWrapper.logic.cs rename to StackInjector/Wrappers/AsyncStackWrapper.logic.cs index f7dae2c..9f879bc 100644 --- a/StackInjector/AsyncStackWrapper.logic.cs +++ b/StackInjector/Wrappers/AsyncStackWrapper.logic.cs @@ -1,8 +1,13 @@ using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; +using StackInjector.Attributes; +using StackInjector.Core; +using StackInjector.Settings; +using StackInjector.Wrappers; -namespace StackInjector +namespace StackInjector.Wrappers { internal partial class AsyncStackWrapper diff --git a/StackInjector/IAsyncStackEntryPoint.cs b/StackInjector/Wrappers/IAsyncStackEntryPoint.cs similarity index 95% rename from StackInjector/IAsyncStackEntryPoint.cs rename to StackInjector/Wrappers/IAsyncStackEntryPoint.cs index 09284d4..f5e5e6d 100644 --- a/StackInjector/IAsyncStackEntryPoint.cs +++ b/StackInjector/Wrappers/IAsyncStackEntryPoint.cs @@ -1,7 +1,7 @@ using System.Threading; using System.Threading.Tasks; -namespace StackInjector +namespace StackInjector.Wrappers { /// /// Entry point for asyncronous StacksWrappers diff --git a/StackInjector/IAsyncStackWrapper.cs b/StackInjector/Wrappers/IAsyncStackWrapper.cs similarity index 97% rename from StackInjector/IAsyncStackWrapper.cs rename to StackInjector/Wrappers/IAsyncStackWrapper.cs index af75507..b5df289 100644 --- a/StackInjector/IAsyncStackWrapper.cs +++ b/StackInjector/Wrappers/IAsyncStackWrapper.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Threading; -namespace StackInjector +namespace StackInjector.Wrappers { /// /// Wraps a Stack of dependency-injected classes, and manages an of completed tasks. diff --git a/StackInjector/IStackEntryPoint.cs b/StackInjector/Wrappers/IStackEntryPoint.cs similarity index 89% rename from StackInjector/IStackEntryPoint.cs rename to StackInjector/Wrappers/IStackEntryPoint.cs index f1fd393..81508db 100644 --- a/StackInjector/IStackEntryPoint.cs +++ b/StackInjector/Wrappers/IStackEntryPoint.cs @@ -1,4 +1,4 @@ -namespace StackInjector +namespace StackInjector.Wrappers { /// /// Defines an entry point for a stack diff --git a/StackInjector/IStackWrapper.cs b/StackInjector/Wrappers/IStackWrapper.cs similarity index 94% rename from StackInjector/IStackWrapper.cs rename to StackInjector/Wrappers/IStackWrapper.cs index 5c8c895..5e0fb62 100644 --- a/StackInjector/IStackWrapper.cs +++ b/StackInjector/Wrappers/IStackWrapper.cs @@ -1,4 +1,6 @@ -namespace StackInjector + + +namespace StackInjector.Wrappers { /// /// Wraps a Stack of dependency-injected classes diff --git a/StackInjector/IStackWrapperStructure.cs b/StackInjector/Wrappers/IStackWrapperStructure.cs similarity index 97% rename from StackInjector/IStackWrapperStructure.cs rename to StackInjector/Wrappers/IStackWrapperStructure.cs index 28e4fe2..ad7d1e8 100644 --- a/StackInjector/IStackWrapperStructure.cs +++ b/StackInjector/Wrappers/IStackWrapperStructure.cs @@ -2,7 +2,7 @@ using StackInjector.Core; using StackInjector.Settings; -namespace StackInjector +namespace StackInjector.Wrappers { /// diff --git a/StackInjector/StackWrapper.cs b/StackInjector/Wrappers/StackWrapper.cs similarity index 86% rename from StackInjector/StackWrapper.cs rename to StackInjector/Wrappers/StackWrapper.cs index cdde2fc..65602de 100644 --- a/StackInjector/StackWrapper.cs +++ b/StackInjector/Wrappers/StackWrapper.cs @@ -7,15 +7,15 @@ using StackInjector.Core; using StackInjector.Settings; -namespace StackInjector +namespace StackInjector.Wrappers { [Service(Version = 1.0, DoNotServeMembers = true)] internal class StackWrapper : StackWrapperBase, IStackWrapper { - internal StackWrapper(WrapperCore core) : base(core,typeof(StackWrapper)) - { } + internal StackWrapper ( WrapperCore core ) : base(core, typeof(StackWrapper)) + { } /// @@ -45,7 +45,7 @@ public override string ToString () public override void Dispose () { - if (!this.disposed) + if( !this.disposed ) { this.Core.RemoveInstancesDiff(); diff --git a/tests/StackInjector.TEST.Async/Services/PowElaborators.cs b/tests/StackInjector.TEST.Async/Services/PowElaborators.cs index dedacd7..480c562 100644 --- a/tests/StackInjector.TEST.Async/Services/PowElaborators.cs +++ b/tests/StackInjector.TEST.Async/Services/PowElaborators.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using StackInjector.Attributes; +using StackInjector.Wrappers; namespace StackInjector.TEST.Async.Services { diff --git a/tests/StackInjector.TEST.Async/Services/TestGenerator.cs b/tests/StackInjector.TEST.Async/Services/TestGenerator.cs index 43e2ee9..5944637 100644 --- a/tests/StackInjector.TEST.Async/Services/TestGenerator.cs +++ b/tests/StackInjector.TEST.Async/Services/TestGenerator.cs @@ -3,6 +3,7 @@ using System.Text; using System.Threading.Tasks; using StackInjector.Attributes; +using StackInjector.Wrappers; namespace StackInjector.TEST.Async.Services { diff --git a/tests/StackInjector.TEST.SimpleStack1/Services/BadThingsGenerators.cs b/tests/StackInjector.TEST.SimpleStack1/Services/BadThingsGenerators.cs index 5f4b370..d0a06bb 100644 --- a/tests/StackInjector.TEST.SimpleStack1/Services/BadThingsGenerators.cs +++ b/tests/StackInjector.TEST.SimpleStack1/Services/BadThingsGenerators.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using StackInjector.Attributes; +using StackInjector.Wrappers; namespace StackInjector.TEST.SimpleStack1.Services { diff --git a/tests/StackInjector.TEST.SimpleStack1/Services/ServiceCloningEntryPoint.cs b/tests/StackInjector.TEST.SimpleStack1/Services/ServiceCloningEntryPoint.cs index 92528a1..3058516 100644 --- a/tests/StackInjector.TEST.SimpleStack1/Services/ServiceCloningEntryPoint.cs +++ b/tests/StackInjector.TEST.SimpleStack1/Services/ServiceCloningEntryPoint.cs @@ -3,6 +3,7 @@ using System.Text; using NUnit.Framework; using StackInjector.Attributes; +using StackInjector.Wrappers; namespace StackInjector.TEST.SimpleStack1.Services { diff --git a/tests/StackInjector.TEST.SimpleStack1/Services/ThingsGenerator.cs b/tests/StackInjector.TEST.SimpleStack1/Services/ThingsGenerator.cs index d25eab5..d75a958 100644 --- a/tests/StackInjector.TEST.SimpleStack1/Services/ThingsGenerator.cs +++ b/tests/StackInjector.TEST.SimpleStack1/Services/ThingsGenerator.cs @@ -1,5 +1,6 @@ using System; using StackInjector.Attributes; +using StackInjector.Wrappers; namespace StackInjector.TEST.SimpleStack1.Services { diff --git a/tests/StackInjector.TEST.Versioning/Services/EntryPoints.cs b/tests/StackInjector.TEST.Versioning/Services/EntryPoints.cs index fe13124..aad276b 100644 --- a/tests/StackInjector.TEST.Versioning/Services/EntryPoints.cs +++ b/tests/StackInjector.TEST.Versioning/Services/EntryPoints.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using StackInjector.Attributes; using StackInjector.Settings; +using StackInjector.Wrappers; namespace StackInjector.TEST.Versioning.Services { From e9b41f2c76d8acd3984224ab32a5e765261ff58d Mon Sep 17 00:00:00 2001 From: JacopoWolf Date: Wed, 13 May 2020 17:11:48 +0200 Subject: [PATCH 03/13] Code cleaning --- StackInjector/Core/StackWrapperBase.cs | 8 ++------ StackInjector/Core/WrapperCore.cs | 1 - StackInjector/Core/WrapperCore.logic.cs | 5 ++--- .../Settings/StackWrapperSettings.configuration.cs | 2 +- StackInjector/Settings/StackWrapperSettings.cs | 6 +++--- StackInjector/Wrappers/AsyncStackWrapper.cs | 4 +--- StackInjector/Wrappers/AsyncStackWrapper.logic.cs | 5 ----- StackInjector/Wrappers/IStackWrapperStructure.cs | 1 - StackInjector/Wrappers/StackWrapper.cs | 7 +------ 9 files changed, 10 insertions(+), 29 deletions(-) diff --git a/StackInjector/Core/StackWrapperBase.cs b/StackInjector/Core/StackWrapperBase.cs index 0a43d26..c5ff5c4 100644 --- a/StackInjector/Core/StackWrapperBase.cs +++ b/StackInjector/Core/StackWrapperBase.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Text; -using StackInjector.Behaviours; -using StackInjector.Core; using StackInjector.Settings; using StackInjector.Wrappers; @@ -10,7 +6,7 @@ namespace StackInjector.Core { internal abstract class StackWrapperBase : IStackWrapperStructure { - public ref readonly StackWrapperSettings Settings + public ref readonly StackWrapperSettings Settings => ref this.Core.settings; @@ -23,7 +19,7 @@ public StackWrapperBase ( WrapperCore core, Type toRegister ) // setting for referencing the calling wrapper as a service if( this.Core.settings.registerSelf ) - this.Core.instances.AddInstance( toRegister , this ); + this.Core.instances.AddInstance(toRegister, this); } diff --git a/StackInjector/Core/WrapperCore.cs b/StackInjector/Core/WrapperCore.cs index 957d9db..37fb1eb 100644 --- a/StackInjector/Core/WrapperCore.cs +++ b/StackInjector/Core/WrapperCore.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Text; using StackInjector.Behaviours; using StackInjector.Settings; diff --git a/StackInjector/Core/WrapperCore.logic.cs b/StackInjector/Core/WrapperCore.logic.cs index 710d76e..1a7f0b5 100644 --- a/StackInjector/Core/WrapperCore.logic.cs +++ b/StackInjector/Core/WrapperCore.logic.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace StackInjector.Core @@ -7,7 +6,7 @@ namespace StackInjector.Core internal partial class WrapperCore { - internal void ServeAll ( ) + internal void ServeAll () { ////// setting for referencing this object from instances inside diff --git a/StackInjector/Settings/StackWrapperSettings.configuration.cs b/StackInjector/Settings/StackWrapperSettings.configuration.cs index 56a7baa..8686aac 100644 --- a/StackInjector/Settings/StackWrapperSettings.configuration.cs +++ b/StackInjector/Settings/StackWrapperSettings.configuration.cs @@ -56,7 +56,7 @@ public StackWrapperSettings RegisterWrapperAsService ( bool register = true ) /// if true, track instances diff /// if true, call Dispose on services implementing /// the modified settings - public StackWrapperSettings TrackInstantiationDiff( bool track = true, bool callDispose = true ) + public StackWrapperSettings TrackInstantiationDiff ( bool track = true, bool callDispose = true ) { this.trackInstancesDiff = track; this.callDisposeOnInstanceDiff = callDispose; diff --git a/StackInjector/Settings/StackWrapperSettings.cs b/StackInjector/Settings/StackWrapperSettings.cs index d79f44d..1ce9d17 100644 --- a/StackInjector/Settings/StackWrapperSettings.cs +++ b/StackInjector/Settings/StackWrapperSettings.cs @@ -42,7 +42,7 @@ private StackWrapperSettings () { } public static StackWrapperSettings Empty => new StackWrapperSettings(); - + /// /// Creates a new StackWrapperSettings with default parameters. @@ -54,9 +54,9 @@ public static StackWrapperSettings Default new StackWrapperSettings() .RegisterEntryAssembly() .RegisterWrapperAsService() - .TrackInstantiationDiff( false ) + .TrackInstantiationDiff(false) .VersioningMethod(ServedVersionTargetingMethod.None, @override: false); - + //todo maybe add a DefaultInner for nested wrappers diff --git a/StackInjector/Wrappers/AsyncStackWrapper.cs b/StackInjector/Wrappers/AsyncStackWrapper.cs index 9dec059..ccdc16a 100644 --- a/StackInjector/Wrappers/AsyncStackWrapper.cs +++ b/StackInjector/Wrappers/AsyncStackWrapper.cs @@ -4,8 +4,6 @@ using System.Threading.Tasks; using StackInjector.Attributes; using StackInjector.Core; -using StackInjector.Settings; -using StackInjector.Wrappers; namespace StackInjector.Wrappers { @@ -32,7 +30,7 @@ internal partial class AsyncStackWrapper : StackWrapperBase, IAsyncStackWrapper /// /// create a new AsyncStackWrapper /// - internal AsyncStackWrapper ( WrapperCore core ) : base(core,typeof(AsyncStackWrapper)) + internal AsyncStackWrapper ( WrapperCore core ) : base(core, typeof(AsyncStackWrapper)) { // register an event that in case the list is empty, release the empty event listener. diff --git a/StackInjector/Wrappers/AsyncStackWrapper.logic.cs b/StackInjector/Wrappers/AsyncStackWrapper.logic.cs index 9f879bc..7471ebb 100644 --- a/StackInjector/Wrappers/AsyncStackWrapper.logic.cs +++ b/StackInjector/Wrappers/AsyncStackWrapper.logic.cs @@ -1,11 +1,6 @@ using System.Collections.Generic; using System.Linq; -using System.Threading; using System.Threading.Tasks; -using StackInjector.Attributes; -using StackInjector.Core; -using StackInjector.Settings; -using StackInjector.Wrappers; namespace StackInjector.Wrappers { diff --git a/StackInjector/Wrappers/IStackWrapperStructure.cs b/StackInjector/Wrappers/IStackWrapperStructure.cs index ad7d1e8..66914d5 100644 --- a/StackInjector/Wrappers/IStackWrapperStructure.cs +++ b/StackInjector/Wrappers/IStackWrapperStructure.cs @@ -1,5 +1,4 @@ using System; -using StackInjector.Core; using StackInjector.Settings; namespace StackInjector.Wrappers diff --git a/StackInjector/Wrappers/StackWrapper.cs b/StackInjector/Wrappers/StackWrapper.cs index 65602de..31b586b 100644 --- a/StackInjector/Wrappers/StackWrapper.cs +++ b/StackInjector/Wrappers/StackWrapper.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; +using System.Linq; using StackInjector.Attributes; -using StackInjector.Behaviours; using StackInjector.Core; -using StackInjector.Settings; namespace StackInjector.Wrappers { From 7d4a816f9a1d404251b4b3acf89165bc888ebff2 Mon Sep 17 00:00:00 2001 From: JacopoWolf Date: Wed, 13 May 2020 18:20:20 +0200 Subject: [PATCH 04/13] Updated core cloning process --- StackInjector/Core/Cloning/ClonedCore.cs | 39 ++++++++++ StackInjector/Core/Cloning/ICloneableCore.cs | 25 +++++++ StackInjector/Core/Cloning/IClonedCore.cs | 28 +++++++ StackInjector/Core/IStackWrapperCore.cs | 20 +++++ StackInjector/Core/StackWrapperBase.cs | 62 --------------- StackInjector/Core/StackWrapperCore.cs | 75 +++++++++++++++++++ StackInjector/Core/WrapperCore.cs | 4 + StackInjector/Injector.cs | 7 +- StackInjector/Wrappers/AsyncStackWrapper.cs | 2 +- StackInjector/Wrappers/IAsyncStackWrapper.cs | 2 +- StackInjector/Wrappers/IStackWrapper.cs | 2 +- .../Wrappers/IStackWrapperStructure.cs | 38 ---------- StackInjector/Wrappers/StackWrapper.cs | 2 +- .../Services/TestGenerator.cs | 2 +- .../Services/ServiceCloningEntryPoint.cs | 7 +- 15 files changed, 203 insertions(+), 112 deletions(-) create mode 100644 StackInjector/Core/Cloning/ClonedCore.cs create mode 100644 StackInjector/Core/Cloning/ICloneableCore.cs create mode 100644 StackInjector/Core/Cloning/IClonedCore.cs create mode 100644 StackInjector/Core/IStackWrapperCore.cs delete mode 100644 StackInjector/Core/StackWrapperBase.cs create mode 100644 StackInjector/Core/StackWrapperCore.cs delete mode 100644 StackInjector/Wrappers/IStackWrapperStructure.cs diff --git a/StackInjector/Core/Cloning/ClonedCore.cs b/StackInjector/Core/Cloning/ClonedCore.cs new file mode 100644 index 0000000..84dc950 --- /dev/null +++ b/StackInjector/Core/Cloning/ClonedCore.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Text; +using StackInjector.Wrappers; + +namespace StackInjector.Core.Cloning +{ + internal class ClonedCore : IClonedCore + { + + private readonly WrapperCore clonedCore; + + internal ClonedCore ( WrapperCore clonedCore ) + => + this.clonedCore = clonedCore; + + + public IAsyncStackWrapper ToAsyncWrapper () where T : IAsyncStackEntryPoint + { + var wrapper = new AsyncStackWrapper( this.clonedCore ); + + this.clonedCore.entryPoint = typeof(T); + this.clonedCore.ServeAll(); + + return wrapper; + } + + + public IStackWrapper ToWrapper () where T : IStackEntryPoint + { + var wrapper = new StackWrapper( this.clonedCore ); + + this.clonedCore.entryPoint = typeof(T); + this.clonedCore.ServeAll(); + + return wrapper; + } + } +} diff --git a/StackInjector/Core/Cloning/ICloneableCore.cs b/StackInjector/Core/Cloning/ICloneableCore.cs new file mode 100644 index 0000000..f7609f5 --- /dev/null +++ b/StackInjector/Core/Cloning/ICloneableCore.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; +using StackInjector.Settings; + +namespace StackInjector.Core.Cloning +{ + + /// + /// Allows for a wrapper to have its core cloned. + /// + public interface ICloneableCore + { + + /// + /// Clone the core of this wrapper, copying the already existing structure + /// and making instantiation of objects faster. + /// + /// if set, overrides the previus core settings. + /// A generic object allowing conversion of the cloned core + IClonedCore CloneCore ( StackWrapperSettings settings = null ); + + } + +} diff --git a/StackInjector/Core/Cloning/IClonedCore.cs b/StackInjector/Core/Cloning/IClonedCore.cs new file mode 100644 index 0000000..1029dde --- /dev/null +++ b/StackInjector/Core/Cloning/IClonedCore.cs @@ -0,0 +1,28 @@ +using StackInjector.Wrappers; + +namespace StackInjector.Core.Cloning +{ + /// + /// A cloned structure of a wrapper. + /// + public interface IClonedCore + { + + /// + /// convert this to an + /// + /// entry point of the new wrapper + /// the new wrapper + IStackWrapper ToWrapper () where T : IStackEntryPoint; + + + /// + /// convert this to an + /// + /// entry point of the new wrapper + /// the new wrapper + IAsyncStackWrapper ToAsyncWrapper () where T : IAsyncStackEntryPoint; + + } + +} diff --git a/StackInjector/Core/IStackWrapperCore.cs b/StackInjector/Core/IStackWrapperCore.cs new file mode 100644 index 0000000..84aa327 --- /dev/null +++ b/StackInjector/Core/IStackWrapperCore.cs @@ -0,0 +1,20 @@ +using System; +using StackInjector.Core.Cloning; +using StackInjector.Settings; + +namespace StackInjector.Wrappers +{ + + /// + /// used to allow cloning of StackWrappers structures + /// + public interface IStackWrapperCore : IDisposable, ICloneableCore + { + + /// + /// the settings of this stackwrapper + /// + ref readonly StackWrapperSettings Settings { get; } + + } +} \ No newline at end of file diff --git a/StackInjector/Core/StackWrapperBase.cs b/StackInjector/Core/StackWrapperBase.cs deleted file mode 100644 index c5ff5c4..0000000 --- a/StackInjector/Core/StackWrapperBase.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using StackInjector.Settings; -using StackInjector.Wrappers; - -namespace StackInjector.Core -{ - internal abstract class StackWrapperBase : IStackWrapperStructure - { - public ref readonly StackWrapperSettings Settings - => ref this.Core.settings; - - - private protected readonly WrapperCore Core; - - - public StackWrapperBase ( WrapperCore core, Type toRegister ) - { - this.Core = core; - - // setting for referencing the calling wrapper as a service - if( this.Core.settings.registerSelf ) - this.Core.instances.AddInstance(toRegister, this); - } - - - public IStackWrapper FromStructure ( StackWrapperSettings overrideSettings = null ) where T : IStackEntryPoint - { - - var clonedCore = new WrapperCore( overrideSettings ?? this.Core.settings ) - { - entryPoint = typeof(T), - instances = this.Core.instances - }; - - var wrapper = new StackWrapper( clonedCore ); - - wrapper.Core.ServeAll(); - - return wrapper; - } - - public IAsyncStackWrapper AsyncFromStructure ( StackWrapperSettings overrideSettings = null ) where T : IAsyncStackEntryPoint - { - var clonedCore = new WrapperCore( overrideSettings ?? this.Core.settings ) - { - entryPoint = typeof(T), - instances = this.Core.instances - }; - - var wrapper = new AsyncStackWrapper( clonedCore ); - - clonedCore.ServeAll(); - - return wrapper; - } - - - - - public abstract void Dispose (); - } -} diff --git a/StackInjector/Core/StackWrapperCore.cs b/StackInjector/Core/StackWrapperCore.cs new file mode 100644 index 0000000..d183c22 --- /dev/null +++ b/StackInjector/Core/StackWrapperCore.cs @@ -0,0 +1,75 @@ +using System; +using StackInjector.Core.Cloning; +using StackInjector.Settings; +using StackInjector.Wrappers; + +namespace StackInjector.Core +{ + internal abstract class StackWrapperCore : IStackWrapperCore + { + public ref readonly StackWrapperSettings Settings + => ref this.Core.settings; + + + private protected readonly WrapperCore Core; + + + public StackWrapperCore ( WrapperCore core, Type toRegister ) + { + this.Core = core; + + // setting for referencing the calling wrapper as a service + if( this.Core.settings.registerSelf ) + this.Core.instances.AddInstance(toRegister, this); + } + + + public IClonedCore CloneCore ( StackWrapperSettings settings = null ) + { + var clonedCore = new WrapperCore( settings ?? this.Core.settings ) + { + instances = this.Core.instances + }; + + return new ClonedCore(clonedCore); + } + + + ////public IStackWrapper FromStructure ( StackWrapperSettings overrideSettings = null ) where T : IStackEntryPoint + ////{ + + //// var clonedCore = new WrapperCore( overrideSettings ?? this.Core.settings ) + //// { + //// entryPoint = typeof(T), + //// instances = this.Core.instances + //// }; + + //// var wrapper = new StackWrapper( clonedCore ); + + //// wrapper.Core.ServeAll(); + + //// return wrapper; + ////} + + ////public IAsyncStackWrapper AsyncFromStructure ( StackWrapperSettings overrideSettings = null ) where T : IAsyncStackEntryPoint + ////{ + //// var clonedCore = new WrapperCore( overrideSettings ?? this.Core.settings ) + //// { + //// entryPoint = typeof(T), + //// instances = this.Core.instances + //// }; + + //// var wrapper = new AsyncStackWrapper( clonedCore ); + + //// clonedCore.ServeAll(); + + //// return wrapper; + ////} + + + + + public abstract void Dispose (); + + } +} diff --git a/StackInjector/Core/WrapperCore.cs b/StackInjector/Core/WrapperCore.cs index 37fb1eb..fd25eb0 100644 --- a/StackInjector/Core/WrapperCore.cs +++ b/StackInjector/Core/WrapperCore.cs @@ -5,6 +5,10 @@ namespace StackInjector.Core { + /// + /// The core common logic of every stack wrapper. + /// The jobs of this class are reflection, versioning, instantiation, and injection. + /// internal partial class WrapperCore { // entry point object of this core diff --git a/StackInjector/Injector.cs b/StackInjector/Injector.cs index c369169..8d28585 100644 --- a/StackInjector/Injector.cs +++ b/StackInjector/Injector.cs @@ -6,12 +6,12 @@ namespace StackInjector { + //todo edit documentation to allow clone cloning /// /// Static factory class exposing methods to create new StackWrappers /// Note that using any of the exposed methods will analyze the whole target assembly, /// If you want to clone an existing structure, see - /// and - /// + /// /// public static class Injector { @@ -58,9 +58,8 @@ public static IStackWrapper From ( StackWrapperSettings settings = null ) whe public static IAsyncStackWrapper AsyncFrom ( StackWrapperSettings settings = null ) where T : IAsyncStackEntryPoint { if( settings == null ) - { settings = StackWrapperSettings.Default; - } + // create a new async stack wrapper var core = new WrapperCore( settings ) diff --git a/StackInjector/Wrappers/AsyncStackWrapper.cs b/StackInjector/Wrappers/AsyncStackWrapper.cs index ccdc16a..74613ea 100644 --- a/StackInjector/Wrappers/AsyncStackWrapper.cs +++ b/StackInjector/Wrappers/AsyncStackWrapper.cs @@ -8,7 +8,7 @@ namespace StackInjector.Wrappers { [Service(DoNotServeMembers = true, Version = 2.0)] - internal partial class AsyncStackWrapper : StackWrapperBase, IAsyncStackWrapper + internal partial class AsyncStackWrapper : StackWrapperCore, IAsyncStackWrapper { // used to cancel everything private readonly CancellationTokenSource cancelPendingTasksSource = new CancellationTokenSource(); diff --git a/StackInjector/Wrappers/IAsyncStackWrapper.cs b/StackInjector/Wrappers/IAsyncStackWrapper.cs index b5df289..81428c7 100644 --- a/StackInjector/Wrappers/IAsyncStackWrapper.cs +++ b/StackInjector/Wrappers/IAsyncStackWrapper.cs @@ -7,7 +7,7 @@ namespace StackInjector.Wrappers /// /// Wraps a Stack of dependency-injected classes, and manages an of completed tasks. /// - public interface IAsyncStackWrapper : IStackWrapperStructure + public interface IAsyncStackWrapper : IStackWrapperCore { /// diff --git a/StackInjector/Wrappers/IStackWrapper.cs b/StackInjector/Wrappers/IStackWrapper.cs index 5e0fb62..0336b8f 100644 --- a/StackInjector/Wrappers/IStackWrapper.cs +++ b/StackInjector/Wrappers/IStackWrapper.cs @@ -5,7 +5,7 @@ namespace StackInjector.Wrappers /// /// Wraps a Stack of dependency-injected classes /// - public interface IStackWrapper : IStackWrapperStructure + public interface IStackWrapper : IStackWrapperCore { /// diff --git a/StackInjector/Wrappers/IStackWrapperStructure.cs b/StackInjector/Wrappers/IStackWrapperStructure.cs deleted file mode 100644 index 66914d5..0000000 --- a/StackInjector/Wrappers/IStackWrapperStructure.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using StackInjector.Settings; - -namespace StackInjector.Wrappers -{ - - /// - /// used to allow cloning of StackWrappers structures - /// - public interface IStackWrapperStructure : IDisposable - { - - /// - /// the settings of this stackwrapper - /// - ref readonly StackWrapperSettings Settings { get; } - - - //todo modify those signatures for generics. Might help. - - /// - /// Copy the structure of this existing wrapper and initialize a new one. - /// - /// - /// if set, overrides this object's settings - /// - IStackWrapper FromStructure ( StackWrapperSettings overrideSettings = null ) where T : IStackEntryPoint; - - /// - /// Copy the structure of this existing wrapper and initialize a new Asyncronous wrapper. - /// - /// - /// if set, overrides this object's settings - /// - IAsyncStackWrapper AsyncFromStructure ( StackWrapperSettings overrideSettings = null ) where T : IAsyncStackEntryPoint; - - } -} diff --git a/StackInjector/Wrappers/StackWrapper.cs b/StackInjector/Wrappers/StackWrapper.cs index 31b586b..18e80b0 100644 --- a/StackInjector/Wrappers/StackWrapper.cs +++ b/StackInjector/Wrappers/StackWrapper.cs @@ -5,7 +5,7 @@ namespace StackInjector.Wrappers { [Service(Version = 1.0, DoNotServeMembers = true)] - internal class StackWrapper : StackWrapperBase, IStackWrapper + internal class StackWrapper : StackWrapperCore, IStackWrapper { diff --git a/tests/StackInjector.TEST.Async/Services/TestGenerator.cs b/tests/StackInjector.TEST.Async/Services/TestGenerator.cs index 5944637..c1b8c47 100644 --- a/tests/StackInjector.TEST.Async/Services/TestGenerator.cs +++ b/tests/StackInjector.TEST.Async/Services/TestGenerator.cs @@ -32,7 +32,7 @@ public object EntryPoint () Console.WriteLine( this.Wrapper.ToString() ); // clone the existing structure and initialize a new asyncronous elaborator! Saves time - using var elaborationWrapper = this.Wrapper.AsyncFromStructure(); + using var elaborationWrapper = this.Wrapper.CloneCore().ToAsyncWrapper(); // logging Console.WriteLine(elaborationWrapper.ToString()); diff --git a/tests/StackInjector.TEST.SimpleStack1/Services/ServiceCloningEntryPoint.cs b/tests/StackInjector.TEST.SimpleStack1/Services/ServiceCloningEntryPoint.cs index 3058516..0ac47fd 100644 --- a/tests/StackInjector.TEST.SimpleStack1/Services/ServiceCloningEntryPoint.cs +++ b/tests/StackInjector.TEST.SimpleStack1/Services/ServiceCloningEntryPoint.cs @@ -13,7 +13,7 @@ class ServiceCloningEntryPoint : IStackEntryPoint IThingsFilter Filter { get; set; } [Served] - IStackWrapperStructure Wrapper { get; set; } + IStackWrapperCore Wrapper { get; set; } public object EntryPoint () { @@ -26,10 +26,11 @@ public object EntryPoint () .TrackInstantiationDiff(); using - ( + ( var wrapper = this.Wrapper - .FromStructure(overrideSettings: settings) + .CloneCore(settings) + .ToWrapper() ) { wrapper.Start(); From ca6c90c9341e5a185076f679295b59c166c693ef Mon Sep 17 00:00:00 2001 From: JacopoWolf Date: Wed, 13 May 2020 19:49:03 +0200 Subject: [PATCH 05/13] Created generic asyncstackwrapper - modified async hierarchy - removed zombie code todo: create async core --- StackInjector/Core/IAsyncStackWrapperCore.cs | 26 +++++++++ StackInjector/Core/IStackWrapperCore.cs | 4 +- StackInjector/Core/StackWrapperCore.cs | 35 ------------ StackInjector/Wrappers/AsyncStackWrapper.cs | 2 +- .../Wrappers/Generic/IAsyncStackWrapper.cs | 56 +++++++++++++++++++ StackInjector/Wrappers/IAsyncStackWrapper.cs | 14 ++--- StackInjector/Wrappers/IStackWrapper.cs | 2 + .../Services/ServiceCloningEntryPoint.cs | 1 + 8 files changed, 92 insertions(+), 48 deletions(-) create mode 100644 StackInjector/Core/IAsyncStackWrapperCore.cs create mode 100644 StackInjector/Wrappers/Generic/IAsyncStackWrapper.cs diff --git a/StackInjector/Core/IAsyncStackWrapperCore.cs b/StackInjector/Core/IAsyncStackWrapperCore.cs new file mode 100644 index 0000000..0a92912 --- /dev/null +++ b/StackInjector/Core/IAsyncStackWrapperCore.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace StackInjector.Core +{ + /// + /// base interface for all asyncronous stackwrappers + /// + public interface IAsyncStackWrapperCore : IStackWrapperCore + { + + /// + /// Used to signal cancellation of every pending task + /// + public CancellationToken PendingTasksCancellationToken { get; } + + + /// + /// check if there are tasks left to elaborate + /// + /// true if there are pending tasks + bool AnyTaskLeft (); + } +} diff --git a/StackInjector/Core/IStackWrapperCore.cs b/StackInjector/Core/IStackWrapperCore.cs index 84aa327..f886f44 100644 --- a/StackInjector/Core/IStackWrapperCore.cs +++ b/StackInjector/Core/IStackWrapperCore.cs @@ -2,11 +2,11 @@ using StackInjector.Core.Cloning; using StackInjector.Settings; -namespace StackInjector.Wrappers +namespace StackInjector.Core { /// - /// used to allow cloning of StackWrappers structures + /// base interface for all stackwrappers /// public interface IStackWrapperCore : IDisposable, ICloneableCore { diff --git a/StackInjector/Core/StackWrapperCore.cs b/StackInjector/Core/StackWrapperCore.cs index d183c22..5e460fa 100644 --- a/StackInjector/Core/StackWrapperCore.cs +++ b/StackInjector/Core/StackWrapperCore.cs @@ -1,7 +1,6 @@ using System; using StackInjector.Core.Cloning; using StackInjector.Settings; -using StackInjector.Wrappers; namespace StackInjector.Core { @@ -35,40 +34,6 @@ public IClonedCore CloneCore ( StackWrapperSettings settings = null ) } - ////public IStackWrapper FromStructure ( StackWrapperSettings overrideSettings = null ) where T : IStackEntryPoint - ////{ - - //// var clonedCore = new WrapperCore( overrideSettings ?? this.Core.settings ) - //// { - //// entryPoint = typeof(T), - //// instances = this.Core.instances - //// }; - - //// var wrapper = new StackWrapper( clonedCore ); - - //// wrapper.Core.ServeAll(); - - //// return wrapper; - ////} - - ////public IAsyncStackWrapper AsyncFromStructure ( StackWrapperSettings overrideSettings = null ) where T : IAsyncStackEntryPoint - ////{ - //// var clonedCore = new WrapperCore( overrideSettings ?? this.Core.settings ) - //// { - //// entryPoint = typeof(T), - //// instances = this.Core.instances - //// }; - - //// var wrapper = new AsyncStackWrapper( clonedCore ); - - //// clonedCore.ServeAll(); - - //// return wrapper; - ////} - - - - public abstract void Dispose (); } diff --git a/StackInjector/Wrappers/AsyncStackWrapper.cs b/StackInjector/Wrappers/AsyncStackWrapper.cs index 74613ea..666bd4b 100644 --- a/StackInjector/Wrappers/AsyncStackWrapper.cs +++ b/StackInjector/Wrappers/AsyncStackWrapper.cs @@ -14,7 +14,7 @@ internal partial class AsyncStackWrapper : StackWrapperCore, IAsyncStackWrapper private readonly CancellationTokenSource cancelPendingTasksSource = new CancellationTokenSource(); // exposes the token - public CancellationToken CancelPendingTasksToken { get => this.cancelPendingTasksSource.Token; } + public CancellationToken PendingTasksCancellationToken { get => this.cancelPendingTasksSource.Token; } // used to lock access to tasks private readonly object listAccessLock = new object(); diff --git a/StackInjector/Wrappers/Generic/IAsyncStackWrapper.cs b/StackInjector/Wrappers/Generic/IAsyncStackWrapper.cs new file mode 100644 index 0000000..9719ed7 --- /dev/null +++ b/StackInjector/Wrappers/Generic/IAsyncStackWrapper.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using StackInjector.Core; + +namespace StackInjector.Wrappers.Generic +{ + /// + /// rappresents a strongly typed generic entry point + /// of an + /// + /// type on the submitted item + /// type of the return item + /// the item to elaborate + /// the cancellation token used to cancel the task + /// a task rappresenting the current job + public delegate Task AsyncStackDigest + ( + TIn item, + CancellationToken cancellationToken + ); + + + /// + /// Wraps a Stack of dependency-injected classes, and manages an of completed tasks. + /// + /// the entry point type, from which to inject services from + /// type submitted to the digest function + /// return type of the Digest function + public interface IAsyncStackWrapper : IAsyncStackWrapperCore + { + /// + /// Called to elaborate submitted items. + /// It's supposed to call a method of + /// + AsyncStackDigest StackDigest { get; } + + /// + /// submit a new item to be elaborated + /// + /// the item to submit + void Submit ( TIn item ); + + /// + /// The loop you ca use to await foreach tasks in elaboration, converted to the specified type. + /// When the pending tasks list is empty, unless is explocitly called + /// this will wait indefinitively. + /// + /// An asyncronous enumerable of completed tasks + IAsyncEnumerable Elaborated (); + + + } +} diff --git a/StackInjector/Wrappers/IAsyncStackWrapper.cs b/StackInjector/Wrappers/IAsyncStackWrapper.cs index 81428c7..17a594b 100644 --- a/StackInjector/Wrappers/IAsyncStackWrapper.cs +++ b/StackInjector/Wrappers/IAsyncStackWrapper.cs @@ -1,19 +1,17 @@ using System; using System.Collections.Generic; using System.Threading; +using StackInjector.Core; namespace StackInjector.Wrappers { /// /// Wraps a Stack of dependency-injected classes, and manages an of completed tasks. /// - public interface IAsyncStackWrapper : IStackWrapperCore + public interface IAsyncStackWrapper : IAsyncStackWrapperCore { - /// - /// Used to signal cancellation of every pending job. - /// - public CancellationToken CancelPendingTasksToken { get; } + /// @@ -33,11 +31,7 @@ public interface IAsyncStackWrapper : IStackWrapperCore /// An asyncronous enumerable of completed tasks IAsyncEnumerable Elaborated (); - /// - /// check if there are tasks left to elaborate - /// - /// true if there are pending tasks - bool AnyTaskLeft (); + } } \ No newline at end of file diff --git a/StackInjector/Wrappers/IStackWrapper.cs b/StackInjector/Wrappers/IStackWrapper.cs index 0336b8f..7911e2d 100644 --- a/StackInjector/Wrappers/IStackWrapper.cs +++ b/StackInjector/Wrappers/IStackWrapper.cs @@ -1,5 +1,7 @@  +using StackInjector.Core; + namespace StackInjector.Wrappers { /// diff --git a/tests/StackInjector.TEST.SimpleStack1/Services/ServiceCloningEntryPoint.cs b/tests/StackInjector.TEST.SimpleStack1/Services/ServiceCloningEntryPoint.cs index 0ac47fd..1eb8096 100644 --- a/tests/StackInjector.TEST.SimpleStack1/Services/ServiceCloningEntryPoint.cs +++ b/tests/StackInjector.TEST.SimpleStack1/Services/ServiceCloningEntryPoint.cs @@ -3,6 +3,7 @@ using System.Text; using NUnit.Framework; using StackInjector.Attributes; +using StackInjector.Core; using StackInjector.Wrappers; namespace StackInjector.TEST.SimpleStack1.Services From cfacef58e35201528f275d4e40e80ce9f9bc8737 Mon Sep 17 00:00:00 2001 From: JacopoWolf Date: Wed, 13 May 2020 23:21:20 +0200 Subject: [PATCH 06/13] Implemented generic async wrapper - completed async logic core - closes #41 - closes #42 --- StackInjector/Core/AsyncStackWrapperCore.cs | 72 ++++++++++++++++++ .../AsyncStackWrapperCore.logic.cs} | 54 ++++++-------- StackInjector/Core/Cloning/ClonedCore.cs | 5 ++ StackInjector/Core/Cloning/IClonedCore.cs | 12 +++ StackInjector/Core/IAsyncStackWrapperCore.cs | 22 +++++- StackInjector/Core/StackWrapperCore.cs | 4 +- StackInjector/Core/WrapperCore.logic.cs | 16 ++-- StackInjector/Injector.cs | 41 ++++++++++- .../Settings/StackWrapperSettings.cs | 2 +- StackInjector/Wrappers/AsyncStackWrapper.cs | 73 +++---------------- .../Wrappers/Generic/AsyncStackWrapper.cs | 39 ++++++++++ .../Wrappers/Generic/IAsyncStackWrapper.cs | 21 ++---- StackInjector/Wrappers/IAsyncStackWrapper.cs | 18 +---- StackInjector/Wrappers/StackWrapper.cs | 2 +- .../Services/PowElaborators.cs | 4 + .../Services/TestGenerator.cs | 4 +- tests/StackInjector.TEST.Async/TestProgram.cs | 39 +++++++++- 17 files changed, 279 insertions(+), 149 deletions(-) create mode 100644 StackInjector/Core/AsyncStackWrapperCore.cs rename StackInjector/{Wrappers/AsyncStackWrapper.logic.cs => Core/AsyncStackWrapperCore.logic.cs} (57%) create mode 100644 StackInjector/Wrappers/Generic/AsyncStackWrapper.cs diff --git a/StackInjector/Core/AsyncStackWrapperCore.cs b/StackInjector/Core/AsyncStackWrapperCore.cs new file mode 100644 index 0000000..77ecae6 --- /dev/null +++ b/StackInjector/Core/AsyncStackWrapperCore.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using StackInjector.Wrappers; + +namespace StackInjector.Core +{ + internal abstract partial class AsyncStackWrapperCore : AsyncStackWrapperCore, IAsyncStackWrapperCore + { + + // used to cancel everything + protected internal readonly CancellationTokenSource cancelPendingTasksSource = new CancellationTokenSource(); + + // exposes the token + public CancellationToken PendingTasksCancellationToken + => this.cancelPendingTasksSource.Token; + + // used to lock access to tasks + protected internal readonly object listAccessLock = new object(); + + // asyncronously waited for new events if TaskList is empty + protected internal readonly SemaphoreSlim emptyListAwaiter = new SemaphoreSlim(0); + + // pending tasks + protected internal LinkedList> tasks = new LinkedList>(); + + + internal AsyncStackWrapperCore ( WrapperCore core, Type toRegister ) : base(core, toRegister) + { + // register an event that in case the list is empty, release the empty event listener. + this.cancelPendingTasksSource.Token.Register(this.ReleaseListAwaiter); + } + + + + #region IDisposable Support + + private bool disposedValue = false; + + public override void Dispose () + { + if( !this.disposedValue ) + { + + // managed resources + this.cancelPendingTasksSource.Cancel(); + this.ReleaseListAwaiter(); // in case it's waiting on the empty list + + this.cancelPendingTasksSource.Dispose(); + this.emptyListAwaiter.Dispose(); + + + // big objects + this.tasks.Clear(); + this.tasks = null; + + // clean instantiated objects + this.Core.RemoveInstancesDiff(); + + + this.disposedValue = true; + } + } + + #endregion + + } +} diff --git a/StackInjector/Wrappers/AsyncStackWrapper.logic.cs b/StackInjector/Core/AsyncStackWrapperCore.logic.cs similarity index 57% rename from StackInjector/Wrappers/AsyncStackWrapper.logic.cs rename to StackInjector/Core/AsyncStackWrapperCore.logic.cs index 7471ebb..3fb3932 100644 --- a/StackInjector/Wrappers/AsyncStackWrapper.logic.cs +++ b/StackInjector/Core/AsyncStackWrapperCore.logic.cs @@ -1,22 +1,23 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; +using System.Text; using System.Threading.Tasks; -namespace StackInjector.Wrappers +namespace StackInjector.Core { - - internal partial class AsyncStackWrapper + internal abstract partial class AsyncStackWrapperCore { - - /// - public void Submit ( object submitted ) + // call the semaphore + protected internal void ReleaseListAwaiter () { - var task = this.GetAsyncEntryPoint().Digest(submitted,this.cancelPendingTasksSource.Token); - + this.emptyListAwaiter.Release(); + } + public void Submit ( Task work ) + { lock( this.listAccessLock ) - this.tasks.AddLast(task); - + this.tasks.AddLast( work ); // if the list was empty just an item ago, signal it's not anymore. // this limit avoids useless cross thread calls that would slow everything down. @@ -24,12 +25,15 @@ public void Submit ( object submitted ) this.ReleaseListAwaiter(); } + public bool AnyTaskLeft () + { + lock( this.listAccessLock ) + return this.tasks.Any(); + } - - /// - public async IAsyncEnumerable Elaborated () + public async IAsyncEnumerable Elaborated () { - while( !this.cancelPendingTasksSource.IsCancellationRequested ) + while( ! this.cancelPendingTasksSource.IsCancellationRequested ) { // avoid deadlocks if( this.tasks.Any() ) @@ -39,7 +43,7 @@ public async IAsyncEnumerable Elaborated () lock( this.listAccessLock ) this.tasks.Remove(completed); - yield return (T)completed.Result; + yield return completed.Result; continue; } else @@ -51,21 +55,5 @@ public async IAsyncEnumerable Elaborated () } } - /// - public bool AnyTaskLeft () - { - lock( this.listAccessLock ) - return this.tasks.Any(); - } - - - /// - /// gets the entry point for this stack - /// - /// - internal IAsyncStackEntryPoint GetAsyncEntryPoint () - => - this.Core.GetEntryPoint(); - } -} +} \ No newline at end of file diff --git a/StackInjector/Core/Cloning/ClonedCore.cs b/StackInjector/Core/Cloning/ClonedCore.cs index 84dc950..b80148e 100644 --- a/StackInjector/Core/Cloning/ClonedCore.cs +++ b/StackInjector/Core/Cloning/ClonedCore.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text; using StackInjector.Wrappers; +using StackInjector.Wrappers.Generic; namespace StackInjector.Core.Cloning { @@ -25,6 +26,10 @@ public IAsyncStackWrapper ToAsyncWrapper () where T : IAsyncStackEntryPoint return wrapper; } + //todo implement + public IAsyncStackWrapper ToGenericAsync ( AsyncStackDigest digest ) + => throw new NotImplementedException(); + public IStackWrapper ToWrapper () where T : IStackEntryPoint { diff --git a/StackInjector/Core/Cloning/IClonedCore.cs b/StackInjector/Core/Cloning/IClonedCore.cs index 1029dde..b0f2d46 100644 --- a/StackInjector/Core/Cloning/IClonedCore.cs +++ b/StackInjector/Core/Cloning/IClonedCore.cs @@ -1,4 +1,5 @@ using StackInjector.Wrappers; +using StackInjector.Wrappers.Generic; namespace StackInjector.Core.Cloning { @@ -23,6 +24,17 @@ public interface IClonedCore /// the new wrapper IAsyncStackWrapper ToAsyncWrapper () where T : IAsyncStackEntryPoint; + + /// + /// convert this to an + /// + /// entry instantiation poin of the new wrapper + /// type of input elements + /// type of output elements + /// action to perform on elements + /// the new wrapper + IAsyncStackWrapper ToGenericAsync ( AsyncStackDigest digest ); + } } diff --git a/StackInjector/Core/IAsyncStackWrapperCore.cs b/StackInjector/Core/IAsyncStackWrapperCore.cs index 0a92912..72cbb32 100644 --- a/StackInjector/Core/IAsyncStackWrapperCore.cs +++ b/StackInjector/Core/IAsyncStackWrapperCore.cs @@ -2,21 +2,37 @@ using System.Collections.Generic; using System.Text; using System.Threading; +using System.Threading.Tasks; namespace StackInjector.Core { /// - /// base interface for all asyncronous stackwrappers + /// base interface for all asyncronous stackwrappers. /// - public interface IAsyncStackWrapperCore : IStackWrapperCore + /// the type tasks will return + public interface IAsyncStackWrapperCore : IStackWrapperCore { /// /// Used to signal cancellation of every pending task /// - public CancellationToken PendingTasksCancellationToken { get; } + CancellationToken PendingTasksCancellationToken { get; } + /// + /// submit new work to this wrapper + /// + /// + void Submit ( Task work ); + + /// + /// The loop you ca use to await foreach tasks in elaboration, converted to the specified type. + /// When the pending tasks list is empty, unless is explocitly called + /// this will wait indefinitively. + /// + /// An asyncronous enumerable of completed tasks + IAsyncEnumerable Elaborated (); + /// /// check if there are tasks left to elaborate /// diff --git a/StackInjector/Core/StackWrapperCore.cs b/StackInjector/Core/StackWrapperCore.cs index 5e460fa..0580330 100644 --- a/StackInjector/Core/StackWrapperCore.cs +++ b/StackInjector/Core/StackWrapperCore.cs @@ -4,7 +4,7 @@ namespace StackInjector.Core { - internal abstract class StackWrapperCore : IStackWrapperCore + internal abstract class AsyncStackWrapperCore : IStackWrapperCore { public ref readonly StackWrapperSettings Settings => ref this.Core.settings; @@ -13,7 +13,7 @@ public ref readonly StackWrapperSettings Settings private protected readonly WrapperCore Core; - public StackWrapperCore ( WrapperCore core, Type toRegister ) + public AsyncStackWrapperCore ( WrapperCore core, Type toRegister ) { this.Core = core; diff --git a/StackInjector/Core/WrapperCore.logic.cs b/StackInjector/Core/WrapperCore.logic.cs index 1a7f0b5..6c24e8a 100644 --- a/StackInjector/Core/WrapperCore.logic.cs +++ b/StackInjector/Core/WrapperCore.logic.cs @@ -8,13 +8,11 @@ internal partial class WrapperCore internal void ServeAll () { - - ////// setting for referencing this object from instances inside - ////if( this.settings.registerSelf ) - //// this.instances.AddInstance(this.GetType(), this); - var toInject = new Queue(); + // saves time in later elaboration + this.entryPoint = this.ClassOrFromInterface(this.entryPoint); + // instantiates and enqueues the EntryPoint toInject.Enqueue ( @@ -29,6 +27,9 @@ internal void ServeAll () foreach( var service in usedServices ) toInject.Enqueue(service); } + + + } @@ -42,10 +43,7 @@ internal T GetEntryPoint () return (T)this .instances - .OfType - ( - this.ClassOrFromInterface(this.entryPoint) - ) + .OfType( this.entryPoint ) .First(); } } diff --git a/StackInjector/Injector.cs b/StackInjector/Injector.cs index 8d28585..a5fce70 100644 --- a/StackInjector/Injector.cs +++ b/StackInjector/Injector.cs @@ -3,10 +3,10 @@ using StackInjector.Exceptions; using StackInjector.Settings; using StackInjector.Wrappers; +using StackInjector.Wrappers.Generic; namespace StackInjector { - //todo edit documentation to allow clone cloning /// /// Static factory class exposing methods to create new StackWrappers /// Note that using any of the exposed methods will analyze the whole target assembly, @@ -64,8 +64,7 @@ public static IAsyncStackWrapper AsyncFrom ( StackWrapperSettings settings = // create a new async stack wrapper var core = new WrapperCore( settings ) { - entryPoint = typeof(T), - instances = new SingleInstanceHolder() + entryPoint = typeof(T) }; var wrapper = new AsyncStackWrapper(core); @@ -76,6 +75,42 @@ public static IAsyncStackWrapper AsyncFrom ( StackWrapperSettings settings = return wrapper; } + /// + /// Create a new generic asyncronous StackWrapper from the + /// entry class with the specified delegate to apply to apply as digest + /// + /// class from which start injection + /// type of elements in input + /// type of elements in output + /// delegate used to call the relative method to perform on submitted items + /// the settings to use with this object. If null, use default. + /// + public static IAsyncStackWrapper AsyncFrom + ( + AsyncStackDigest digest, + StackWrapperSettings settings = null + ) + { + if( settings == null ) + settings = StackWrapperSettings.Default; + + // create a new generic async wrapper + var core = new WrapperCore( settings ) + { + entryPoint = typeof(TEntry) + }; + + var wrapper = new AsyncStackWrapper(core) + { + StackDigest = digest + }; + + core.ReadAssemblies(); + core.ServeAll(); + + return wrapper; + } + } } diff --git a/StackInjector/Settings/StackWrapperSettings.cs b/StackInjector/Settings/StackWrapperSettings.cs index 1ce9d17..8839677 100644 --- a/StackInjector/Settings/StackWrapperSettings.cs +++ b/StackInjector/Settings/StackWrapperSettings.cs @@ -58,7 +58,7 @@ public static StackWrapperSettings Default .VersioningMethod(ServedVersionTargetingMethod.None, @override: false); - //todo maybe add a DefaultInner for nested wrappers + //? maybe add a DefaultInner for nested wrappers #endregion diff --git a/StackInjector/Wrappers/AsyncStackWrapper.cs b/StackInjector/Wrappers/AsyncStackWrapper.cs index 666bd4b..2bddc48 100644 --- a/StackInjector/Wrappers/AsyncStackWrapper.cs +++ b/StackInjector/Wrappers/AsyncStackWrapper.cs @@ -8,44 +8,26 @@ namespace StackInjector.Wrappers { [Service(DoNotServeMembers = true, Version = 2.0)] - internal partial class AsyncStackWrapper : StackWrapperCore, IAsyncStackWrapper + internal partial class AsyncStackWrapper : AsyncStackWrapperCore, IAsyncStackWrapper { - // used to cancel everything - private readonly CancellationTokenSource cancelPendingTasksSource = new CancellationTokenSource(); - - // exposes the token - public CancellationToken PendingTasksCancellationToken { get => this.cancelPendingTasksSource.Token; } - - // used to lock access to tasks - private readonly object listAccessLock = new object(); - - // asyncronously waited for new events if TaskList is empty - private readonly SemaphoreSlim emptyListAwaiter = new SemaphoreSlim(0); - - // pending tasks - private LinkedList> tasks = new LinkedList>(); - - /// /// create a new AsyncStackWrapper /// internal AsyncStackWrapper ( WrapperCore core ) : base(core, typeof(AsyncStackWrapper)) - { + { } - // register an event that in case the list is empty, release the empty event listener. - this.cancelPendingTasksSource.Token.Register(this.ReleaseListAwaiter); - } - - - /// - /// call the semaphore - /// - private void ReleaseListAwaiter () - => - this.emptyListAwaiter.Release(); + public void Submit ( object item ) + { + var task = + this + .Core + .GetEntryPoint() + .Digest(item, this.PendingTasksCancellationToken); + base.Submit(task); + } public override string ToString () @@ -53,38 +35,5 @@ public override string ToString () $"AsyncStackWrapper{{ {this.Core.instances.GetAllTypes().Count()} registered types; " + $"entry point: {this.Core.entryPoint.Name}; canceled: {this.cancelPendingTasksSource.IsCancellationRequested} }}"; - - - #region IDisposable Support - - private bool disposedValue = false; - - public override void Dispose () - { - if( !this.disposedValue ) - { - - // managed resources - this.cancelPendingTasksSource.Cancel(); - this.ReleaseListAwaiter(); // in case it's waiting on the empty list - - this.cancelPendingTasksSource.Dispose(); - this.emptyListAwaiter.Dispose(); - - - // big objects - this.tasks.Clear(); - this.tasks = null; - - // clean instantiated objects - this.Core.RemoveInstancesDiff(); - - - this.disposedValue = true; - } - } - - #endregion - } } \ No newline at end of file diff --git a/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs b/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs new file mode 100644 index 0000000..11e33ad --- /dev/null +++ b/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using StackInjector.Attributes; +using StackInjector.Core; + +namespace StackInjector.Wrappers.Generic +{ + [Service(Version = 2.1, DoNotServeMembers = true)] + internal class AsyncStackWrapper : AsyncStackWrapperCore, IAsyncStackWrapper + { + + public AsyncStackDigest StackDigest { get; internal set; } + + public AsyncStackWrapper ( WrapperCore core ) : base(core, typeof(AsyncStackWrapper)) + { } + + public void Submit ( TIn item ) + { + base.Submit + ( + this.StackDigest.Invoke + ( + this.Core.GetEntryPoint(), + item, + this.PendingTasksCancellationToken + ) + ); + } + + public override string ToString () + => + $"AsyncStackWrapper<{typeof(TEntry).Name},{typeof(TIn).Name},{typeof(TOut).Name}>" + + $"{{ {this.Core.instances.GetAllTypes().Count()} registered types; " + + $"canceled: {this.cancelPendingTasksSource.IsCancellationRequested} }}"; + + } +} diff --git a/StackInjector/Wrappers/Generic/IAsyncStackWrapper.cs b/StackInjector/Wrappers/Generic/IAsyncStackWrapper.cs index 9719ed7..ac1f857 100644 --- a/StackInjector/Wrappers/Generic/IAsyncStackWrapper.cs +++ b/StackInjector/Wrappers/Generic/IAsyncStackWrapper.cs @@ -11,13 +11,16 @@ namespace StackInjector.Wrappers.Generic /// rappresents a strongly typed generic entry point /// of an /// + /// the entry type of this object /// type on the submitted item /// type of the return item + /// the instance of the entry /// the item to elaborate /// the cancellation token used to cancel the task /// a task rappresenting the current job - public delegate Task AsyncStackDigest + public delegate Task AsyncStackDigest ( + TEntry instance, TIn item, CancellationToken cancellationToken ); @@ -26,16 +29,15 @@ CancellationToken cancellationToken /// /// Wraps a Stack of dependency-injected classes, and manages an of completed tasks. /// - /// the entry point type, from which to inject services from + /// /// type submitted to the digest function /// return type of the Digest function - public interface IAsyncStackWrapper : IAsyncStackWrapperCore + public interface IAsyncStackWrapper : IAsyncStackWrapperCore { /// /// Called to elaborate submitted items. - /// It's supposed to call a method of /// - AsyncStackDigest StackDigest { get; } + AsyncStackDigest StackDigest { get; } /// /// submit a new item to be elaborated @@ -43,14 +45,5 @@ public interface IAsyncStackWrapper : IAsyncStackWrapperCo /// the item to submit void Submit ( TIn item ); - /// - /// The loop you ca use to await foreach tasks in elaboration, converted to the specified type. - /// When the pending tasks list is empty, unless is explocitly called - /// this will wait indefinitively. - /// - /// An asyncronous enumerable of completed tasks - IAsyncEnumerable Elaborated (); - - } } diff --git a/StackInjector/Wrappers/IAsyncStackWrapper.cs b/StackInjector/Wrappers/IAsyncStackWrapper.cs index 17a594b..c6373ef 100644 --- a/StackInjector/Wrappers/IAsyncStackWrapper.cs +++ b/StackInjector/Wrappers/IAsyncStackWrapper.cs @@ -8,30 +8,14 @@ namespace StackInjector.Wrappers /// /// Wraps a Stack of dependency-injected classes, and manages an of completed tasks. /// - public interface IAsyncStackWrapper : IAsyncStackWrapperCore + public interface IAsyncStackWrapper : IAsyncStackWrapperCore { - - - /// /// Submit a new object to be elaborated asyncronously in this stack /// /// The object to elaborate void Submit ( object submitted ); - - /// - /// The loop you ca use to await foreach tasks in elaboration, converted to the specified type. - /// When the pending tasks list is empty, unless is explocitly called - /// this will wait indefinitively. - /// - /// Type to cast the object returned by the entry point - /// - /// An asyncronous enumerable of completed tasks - IAsyncEnumerable Elaborated (); - - - } } \ No newline at end of file diff --git a/StackInjector/Wrappers/StackWrapper.cs b/StackInjector/Wrappers/StackWrapper.cs index 18e80b0..e5cb148 100644 --- a/StackInjector/Wrappers/StackWrapper.cs +++ b/StackInjector/Wrappers/StackWrapper.cs @@ -5,7 +5,7 @@ namespace StackInjector.Wrappers { [Service(Version = 1.0, DoNotServeMembers = true)] - internal class StackWrapper : StackWrapperCore, IStackWrapper + internal class StackWrapper : AsyncStackWrapperCore, IStackWrapper { diff --git a/tests/StackInjector.TEST.Async/Services/PowElaborators.cs b/tests/StackInjector.TEST.Async/Services/PowElaborators.cs index 480c562..be2977f 100644 --- a/tests/StackInjector.TEST.Async/Services/PowElaborators.cs +++ b/tests/StackInjector.TEST.Async/Services/PowElaborators.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using StackInjector.Attributes; +using StackInjector.Core; using StackInjector.Wrappers; namespace StackInjector.TEST.Async.Services @@ -19,6 +20,9 @@ class MathService class PowElaborator : IAsyncStackEntryPoint { + [Served] + IStackWrapperCore wrapper; + [Served] MathService MathService { get; set; } diff --git a/tests/StackInjector.TEST.Async/Services/TestGenerator.cs b/tests/StackInjector.TEST.Async/Services/TestGenerator.cs index c1b8c47..4ac1671 100644 --- a/tests/StackInjector.TEST.Async/Services/TestGenerator.cs +++ b/tests/StackInjector.TEST.Async/Services/TestGenerator.cs @@ -47,9 +47,9 @@ async Task> waitForRes () List results = new List(); int counter = 2; - await foreach( var res in elaborationWrapper.Elaborated() ) + await foreach( var res in elaborationWrapper.Elaborated() ) if( counter++ < 18 ) // we don't want to wait forever. - results.Add(res); + results.Add( (double)res ); else break; diff --git a/tests/StackInjector.TEST.Async/TestProgram.cs b/tests/StackInjector.TEST.Async/TestProgram.cs index 471be46..cb1809b 100644 --- a/tests/StackInjector.TEST.Async/TestProgram.cs +++ b/tests/StackInjector.TEST.Async/TestProgram.cs @@ -11,7 +11,7 @@ namespace StackInjector.TEST.Async { public class Tests { - [Test][Retry(5)] + [Test] public async Task TestAsync () { var feed = Enumerable.Range(1, 11); @@ -34,7 +34,7 @@ public async Task TestAsync () ); var counter = 0; - await foreach( var result in asyncwrapper.Elaborated() ) + await foreach( var result in asyncwrapper.Elaborated() ) if( counter++ < 10 ) Console.Write($"{result}; "); else @@ -45,6 +45,41 @@ public async Task TestAsync () } + // this test is 5-10 milliseconds FASTER than the generic counterpart. + // I guess type safety really fastens it up a lot + [Test] + public async Task TestGenericAsync() + { + var feed = Enumerable.Range(1, 11); + + using var wrapper = Injector.AsyncFrom( async (i,e,t) => (double) await i.Digest(e,t) ); + + // takes up to 1 second, waiting for 0.1 seconds every submission + var feeder = Task.Run + ( + () => + { + foreach( var item in feed ) + { + wrapper.Submit(item); + + Thread.Sleep(10); // same as above + } + } + ); + + var counter = 0; + await foreach( var result in wrapper.Elaborated() ) + if( counter++ < 10 ) + Console.Write($"{result}; "); + else + break; + + Assert.AreEqual(feed.Count(), counter); + + } + + [Test] public void ServeAsync () { From 578dfc1c148dfc8fb4f4c098efdaf881f02ca694 Mon Sep 17 00:00:00 2001 From: JacopoWolf Date: Sat, 16 May 2020 18:02:33 +0200 Subject: [PATCH 07/13] Solved #45 - updates settings - updated tests --- .../Core/AsyncStackWrapperCore.logic.cs | 48 ++++++++++++-- StackInjector/Core/IAsyncStackWrapperCore.cs | 6 ++ StackInjector/Settings/AsyncWaitingMethod.cs | 28 ++++++++ .../StackWrapperSettings.configuration.cs | 26 ++++++++ .../Settings/StackWrapperSettings.cs | 13 ++-- .../Services/PowElaborators.cs | 3 - tests/StackInjector.TEST.Async/TestProgram.cs | 66 +++++++++++-------- 7 files changed, 149 insertions(+), 41 deletions(-) create mode 100644 StackInjector/Settings/AsyncWaitingMethod.cs diff --git a/StackInjector/Core/AsyncStackWrapperCore.logic.cs b/StackInjector/Core/AsyncStackWrapperCore.logic.cs index 3fb3932..b5d026e 100644 --- a/StackInjector/Core/AsyncStackWrapperCore.logic.cs +++ b/StackInjector/Core/AsyncStackWrapperCore.logic.cs @@ -1,8 +1,11 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; +using StackInjector.Settings; namespace StackInjector.Core { @@ -36,7 +39,7 @@ public async IAsyncEnumerable Elaborated () while( ! this.cancelPendingTasksSource.IsCancellationRequested ) { // avoid deadlocks - if( this.tasks.Any() ) + if( this.AnyTaskLeft() ) { var completed = await Task.WhenAny(this.tasks).ConfigureAwait(false); @@ -48,12 +51,49 @@ public async IAsyncEnumerable Elaborated () } else { - // wait for a signal of the list not being empty anymore - await this.emptyListAwaiter.WaitAsync().ConfigureAwait(true); - continue; + if( await this.OnNoTasksLeft().ConfigureAwait(true) ) + break; } } } + // true if outher loop is to break + private async Task OnNoTasksLeft () + { + // to not repeat code + Task listAwaiter () + => this.emptyListAwaiter.WaitAsync(); + + + switch( this.Settings.asyncWaitingMethod ) + { + + case AsyncWaitingMethod.Exit: + default: + + return true; + + + case AsyncWaitingMethod.Wait: + + // wait for a signal of the list not being empty anymore + await listAwaiter().ConfigureAwait(true); + return false; + + + case AsyncWaitingMethod.WaitTimeout: + var list = listAwaiter(); + var timeout = Task.Delay( this.Settings.asyncWaitTime ); + + return ( await Task.WhenAny(list, timeout).ConfigureAwait(true) ) == timeout; + } + } + + + public bool AnyTaskCompleted () + => + this.tasks.Any(t => t.IsCompleted); + + } } \ No newline at end of file diff --git a/StackInjector/Core/IAsyncStackWrapperCore.cs b/StackInjector/Core/IAsyncStackWrapperCore.cs index 72cbb32..ee32476 100644 --- a/StackInjector/Core/IAsyncStackWrapperCore.cs +++ b/StackInjector/Core/IAsyncStackWrapperCore.cs @@ -38,5 +38,11 @@ public interface IAsyncStackWrapperCore : IStackWrapperCore /// /// true if there are pending tasks bool AnyTaskLeft (); + + /// + /// check if any pending task has been completed + /// + /// true if any task completed + bool AnyTaskCompleted (); } } diff --git a/StackInjector/Settings/AsyncWaitingMethod.cs b/StackInjector/Settings/AsyncWaitingMethod.cs new file mode 100644 index 0000000..09f7cb1 --- /dev/null +++ b/StackInjector/Settings/AsyncWaitingMethod.cs @@ -0,0 +1,28 @@ +namespace StackInjector.Settings +{ + + /// + /// How should an behave when there are no tasks? + /// + public enum AsyncWaitingMethod + { + + /// + /// Simply exit the await foreach loop withouth doing anything + /// + Exit, + + /// + /// don't exit the loop, but wait for new Tasks to be submitted. + /// Exiting the loop requires Dispose() to be called on the wrapper or a break + /// + Wait, + + /// + /// don't immediately exit the loop, but rather wait a certain amount of time before exiting the loop + /// + WaitTimeout + + + } +} \ No newline at end of file diff --git a/StackInjector/Settings/StackWrapperSettings.configuration.cs b/StackInjector/Settings/StackWrapperSettings.configuration.cs index 8686aac..1c42f8b 100644 --- a/StackInjector/Settings/StackWrapperSettings.configuration.cs +++ b/StackInjector/Settings/StackWrapperSettings.configuration.cs @@ -4,6 +4,9 @@ namespace StackInjector.Settings { public sealed partial class StackWrapperSettings { + + #region Assembly registration + /// /// register an external assembly from wich you want classes to be laoded /// @@ -50,6 +53,9 @@ public StackWrapperSettings RegisterWrapperAsService ( bool register = true ) return this; } + #endregion + + /// /// Track every new instantiated class to be deleted upon Dispose. /// @@ -75,5 +81,25 @@ public StackWrapperSettings VersioningMethod ( ServedVersionTargetingMethod targ this.overrideTargetingMethod = @override; return this; } + + + #region Asynchronous settings + + /// + /// What to do when an + /// has no more pending tasks to execute + /// + /// the new waiting method + /// if is set, this will be max time to wait + /// the modified settings + public StackWrapperSettings WhenNoMoreTasks ( AsyncWaitingMethod waitingMethod, int waitTime = 1000 ) + { + this.asyncWaitingMethod = waitingMethod; + this.asyncWaitTime = waitTime; + return this; + } + + #endregion + } } diff --git a/StackInjector/Settings/StackWrapperSettings.cs b/StackInjector/Settings/StackWrapperSettings.cs index 8839677..ae088b1 100644 --- a/StackInjector/Settings/StackWrapperSettings.cs +++ b/StackInjector/Settings/StackWrapperSettings.cs @@ -27,10 +27,12 @@ public sealed partial class StackWrapperSettings internal bool trackInstancesDiff; internal bool callDisposeOnInstanceDiff; - #endregion - + // async management + internal AsyncWaitingMethod asyncWaitingMethod; + internal int asyncWaitTime; + - #region constructors + #endregion private StackWrapperSettings () { } @@ -55,12 +57,11 @@ public static StackWrapperSettings Default .RegisterEntryAssembly() .RegisterWrapperAsService() .TrackInstantiationDiff(false) - .VersioningMethod(ServedVersionTargetingMethod.None, @override: false); + .VersioningMethod(ServedVersionTargetingMethod.None, @override: false) + .WhenNoMoreTasks(AsyncWaitingMethod.Wait); //? maybe add a DefaultInner for nested wrappers - #endregion - } } diff --git a/tests/StackInjector.TEST.Async/Services/PowElaborators.cs b/tests/StackInjector.TEST.Async/Services/PowElaborators.cs index be2977f..5a0226a 100644 --- a/tests/StackInjector.TEST.Async/Services/PowElaborators.cs +++ b/tests/StackInjector.TEST.Async/Services/PowElaborators.cs @@ -20,9 +20,6 @@ class MathService class PowElaborator : IAsyncStackEntryPoint { - [Served] - IStackWrapperCore wrapper; - [Served] MathService MathService { get; set; } diff --git a/tests/StackInjector.TEST.Async/TestProgram.cs b/tests/StackInjector.TEST.Async/TestProgram.cs index cb1809b..cd71f1c 100644 --- a/tests/StackInjector.TEST.Async/TestProgram.cs +++ b/tests/StackInjector.TEST.Async/TestProgram.cs @@ -11,12 +11,17 @@ namespace StackInjector.TEST.Async { public class Tests { - [Test] + [Test][Retry(3)] public async Task TestAsync () { var feed = Enumerable.Range(1, 11); - using var asyncwrapper = Injector.AsyncFrom(); + // wait for a maximum of 500 milliseconds + var settings = + StackWrapperSettings.Default + .WhenNoMoreTasks(AsyncWaitingMethod.WaitTimeout, 500 ); + + using var asyncwrapper = Injector.AsyncFrom( settings ); // takes up to 1 second, waiting for 0.1 seconds every submission var feeder = Task.Run @@ -26,21 +31,23 @@ public async Task TestAsync () foreach( var item in feed ) { asyncwrapper.Submit(item); - - Thread.Sleep(10); // <<<----- I want to highlight this this is for asyncronous testing purposes - // and it's the cause of the 100+ milliseconds of elaboration required for this test } } ); - var counter = 0; + // submit a new element ~100 milliseconds before the wrapper exits the loop + var test = Task.Run( async () => { await Task.Delay(400); asyncwrapper.Submit(42); }); + + + var resStr = ""; + await foreach( var result in asyncwrapper.Elaborated() ) - if( counter++ < 10 ) - Console.Write($"{result}; "); - else - asyncwrapper.Dispose(); // test if disposing of asyncwrapper will stop the loop + resStr += $"{result}; "; - Assert.AreEqual(feed.Count(), counter); + await test; + await feeder; + + Assert.AreEqual( resStr , "1; 4; 9; 16; 25; 36; 49; 64; 81; 100; 121; 1764; " ); } @@ -52,28 +59,31 @@ public async Task TestGenericAsync() { var feed = Enumerable.Range(1, 11); - using var wrapper = Injector.AsyncFrom( async (i,e,t) => (double) await i.Digest(e,t) ); + var settings = + StackWrapperSettings.Default + .WhenNoMoreTasks(AsyncWaitingMethod.Exit); - // takes up to 1 second, waiting for 0.1 seconds every submission - var feeder = Task.Run - ( - () => - { - foreach( var item in feed ) - { - wrapper.Submit(item); + using var wrapper = + Injector.AsyncFrom + ( + // could call any method here + async (i,e,t) => (double) await i.Digest(e,t), + settings + ); + + Console.WriteLine(wrapper); + + + foreach( var item in feed ) + wrapper.Submit(item); - Thread.Sleep(10); // same as above - } - } - ); var counter = 0; await foreach( var result in wrapper.Elaborated() ) - if( counter++ < 10 ) - Console.Write($"{result}; "); - else - break; + { + counter++; + Console.Write($"{result}; "); + } Assert.AreEqual(feed.Count(), counter); From ec4befc7fc43d0f831c0322f60e8dd6966ee7365 Mon Sep 17 00:00:00 2001 From: JacopoWolf Date: Sat, 16 May 2020 18:05:15 +0200 Subject: [PATCH 08/13] Update ClonedCore.cs --- StackInjector/Core/Cloning/ClonedCore.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/StackInjector/Core/Cloning/ClonedCore.cs b/StackInjector/Core/Cloning/ClonedCore.cs index b80148e..405e6e0 100644 --- a/StackInjector/Core/Cloning/ClonedCore.cs +++ b/StackInjector/Core/Cloning/ClonedCore.cs @@ -26,9 +26,15 @@ public IAsyncStackWrapper ToAsyncWrapper () where T : IAsyncStackEntryPoint return wrapper; } - //todo implement - public IAsyncStackWrapper ToGenericAsync ( AsyncStackDigest digest ) - => throw new NotImplementedException(); + public IAsyncStackWrapper ToGenericAsync ( AsyncStackDigest digest ) + { + var wrapper = new AsyncStackWrapper( this.clonedCore ); + + this.clonedCore.entryPoint = typeof(TEntry); + this.clonedCore.ServeAll(); + + return wrapper; + } public IStackWrapper ToWrapper () where T : IStackEntryPoint From 14644404e6037def314667b53146599e0392161f Mon Sep 17 00:00:00 2001 From: JacopoWolf Date: Sat, 16 May 2020 18:13:12 +0200 Subject: [PATCH 09/13] Update WrapperCore.injection.cs separated injection into specific methods --- StackInjector/Core/WrapperCore.injection.cs | 62 +++++++++++---------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/StackInjector/Core/WrapperCore.injection.cs b/StackInjector/Core/WrapperCore.injection.cs index 3bf6199..39ef865 100644 --- a/StackInjector/Core/WrapperCore.injection.cs +++ b/StackInjector/Core/WrapperCore.injection.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using StackInjector.Attributes; @@ -7,15 +8,12 @@ namespace StackInjector.Core { internal partial class WrapperCore { - //! maintainability of 52/100 - //todo simplify this method - /// /// Injects services into the specified instance, instantiating them on necessity. /// /// /// - internal virtual IEnumerable InjectServicesInto ( object instance ) + internal IEnumerable InjectServicesInto ( object instance ) { var instantiated = new List(); var type = instance.GetType(); @@ -24,42 +22,50 @@ internal virtual IEnumerable InjectServicesInto ( object instance ) if( type.GetCustomAttribute()?.DoNotServeMembers ?? false ) return instantiated; - // fields - { - var fields = + this.InjectFields(type, instance, ref instantiated); + this.InjectProperties(type, instance, ref instantiated); + + + return instantiated; + } + + #region injection methods + + private void InjectFields( Type type, object instance, ref List instantiated ) + { + var fields = type .GetFields( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ) .Where( field => field.GetCustomAttribute() != null ); - foreach( var serviceField in fields ) - { - var serviceType = this.ClassOrFromInterface(serviceField.FieldType, serviceField.GetCustomAttribute()); - var serviceInstance = this.OfTypeOrInstantiate(serviceType); - serviceField.SetValue(instance, serviceInstance); + foreach( var serviceField in fields ) + { + var serviceType = this.ClassOrFromInterface(serviceField.FieldType, serviceField.GetCustomAttribute()); + var serviceInstance = this.OfTypeOrInstantiate(serviceType); + serviceField.SetValue(instance, serviceInstance); - instantiated.Add(serviceInstance); - } + instantiated.Add(serviceInstance); } + } - // properties - { - var properties = + private void InjectProperties ( Type type, object instance, ref List instantiated ) + { + var properties = type .GetProperties( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ) .Where( property => property.GetCustomAttribute() != null ); - foreach( var propertyField in properties ) - { - var serviceType = this.ClassOrFromInterface( propertyField.PropertyType, propertyField.GetCustomAttribute() ); - var serviceInstance = this.OfTypeOrInstantiate( serviceType ); - propertyField.SetValue(instance, serviceInstance); - - instantiated.Add(serviceInstance); - } + foreach( var propertyField in properties ) + { + var serviceType = this.ClassOrFromInterface( propertyField.PropertyType, propertyField.GetCustomAttribute() ); + var serviceInstance = this.OfTypeOrInstantiate( serviceType ); + propertyField.SetValue(instance, serviceInstance); + instantiated.Add(serviceInstance); } - - return instantiated; } + + #endregion + } } From e035d106dff4fc9668594d3b58843c27836b2eee Mon Sep 17 00:00:00 2001 From: JacopoWolf Date: Sat, 16 May 2020 18:14:19 +0200 Subject: [PATCH 10/13] Code cleanup --- StackInjector/Core/AsyncStackWrapperCore.cs | 6 +----- .../Core/AsyncStackWrapperCore.logic.cs | 16 ++++++---------- StackInjector/Core/Cloning/ClonedCore.cs | 9 +++------ StackInjector/Core/Cloning/ICloneableCore.cs | 5 +---- StackInjector/Core/Cloning/IClonedCore.cs | 2 +- StackInjector/Core/IAsyncStackWrapperCore.cs | 1 - StackInjector/Core/StackWrapperCore.cs | 2 +- StackInjector/Core/WrapperCore.injection.cs | 2 +- StackInjector/Core/WrapperCore.logic.cs | 2 +- StackInjector/Injector.cs | 9 ++++----- StackInjector/Settings/StackWrapperSettings.cs | 2 +- StackInjector/Wrappers/AsyncStackWrapper.cs | 9 +++------ .../Wrappers/Generic/AsyncStackWrapper.cs | 5 +---- .../Wrappers/Generic/IAsyncStackWrapper.cs | 12 +++++------- StackInjector/Wrappers/IAsyncStackWrapper.cs | 4 +--- 15 files changed, 30 insertions(+), 56 deletions(-) diff --git a/StackInjector/Core/AsyncStackWrapperCore.cs b/StackInjector/Core/AsyncStackWrapperCore.cs index 77ecae6..13b6d14 100644 --- a/StackInjector/Core/AsyncStackWrapperCore.cs +++ b/StackInjector/Core/AsyncStackWrapperCore.cs @@ -1,11 +1,7 @@ using System; using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; -using StackInjector.Wrappers; namespace StackInjector.Core { @@ -16,7 +12,7 @@ internal abstract partial class AsyncStackWrapperCore : AsyncStackWrapperCore protected internal readonly CancellationTokenSource cancelPendingTasksSource = new CancellationTokenSource(); // exposes the token - public CancellationToken PendingTasksCancellationToken + public CancellationToken PendingTasksCancellationToken => this.cancelPendingTasksSource.Token; // used to lock access to tasks diff --git a/StackInjector/Core/AsyncStackWrapperCore.logic.cs b/StackInjector/Core/AsyncStackWrapperCore.logic.cs index b5d026e..86735e3 100644 --- a/StackInjector/Core/AsyncStackWrapperCore.logic.cs +++ b/StackInjector/Core/AsyncStackWrapperCore.logic.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; +using System.Collections.Generic; using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; using System.Threading.Tasks; using StackInjector.Settings; @@ -20,7 +16,7 @@ protected internal void ReleaseListAwaiter () public void Submit ( Task work ) { lock( this.listAccessLock ) - this.tasks.AddLast( work ); + this.tasks.AddLast(work); // if the list was empty just an item ago, signal it's not anymore. // this limit avoids useless cross thread calls that would slow everything down. @@ -36,7 +32,7 @@ public bool AnyTaskLeft () public async IAsyncEnumerable Elaborated () { - while( ! this.cancelPendingTasksSource.IsCancellationRequested ) + while( !this.cancelPendingTasksSource.IsCancellationRequested ) { // avoid deadlocks if( this.AnyTaskLeft() ) @@ -67,7 +63,7 @@ Task listAwaiter () switch( this.Settings.asyncWaitingMethod ) { - + case AsyncWaitingMethod.Exit: default: @@ -85,7 +81,7 @@ Task listAwaiter () var list = listAwaiter(); var timeout = Task.Delay( this.Settings.asyncWaitTime ); - return ( await Task.WhenAny(list, timeout).ConfigureAwait(true) ) == timeout; + return (await Task.WhenAny(list, timeout).ConfigureAwait(true)) == timeout; } } @@ -93,7 +89,7 @@ Task listAwaiter () public bool AnyTaskCompleted () => this.tasks.Any(t => t.IsCompleted); - + } } \ No newline at end of file diff --git a/StackInjector/Core/Cloning/ClonedCore.cs b/StackInjector/Core/Cloning/ClonedCore.cs index 405e6e0..a36a22d 100644 --- a/StackInjector/Core/Cloning/ClonedCore.cs +++ b/StackInjector/Core/Cloning/ClonedCore.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using StackInjector.Wrappers; +using StackInjector.Wrappers; using StackInjector.Wrappers.Generic; namespace StackInjector.Core.Cloning @@ -11,8 +8,8 @@ internal class ClonedCore : IClonedCore private readonly WrapperCore clonedCore; - internal ClonedCore ( WrapperCore clonedCore ) - => + internal ClonedCore ( WrapperCore clonedCore ) + => this.clonedCore = clonedCore; diff --git a/StackInjector/Core/Cloning/ICloneableCore.cs b/StackInjector/Core/Cloning/ICloneableCore.cs index f7609f5..fe28c7e 100644 --- a/StackInjector/Core/Cloning/ICloneableCore.cs +++ b/StackInjector/Core/Cloning/ICloneableCore.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using StackInjector.Settings; +using StackInjector.Settings; namespace StackInjector.Core.Cloning { diff --git a/StackInjector/Core/Cloning/IClonedCore.cs b/StackInjector/Core/Cloning/IClonedCore.cs index b0f2d46..b79efbe 100644 --- a/StackInjector/Core/Cloning/IClonedCore.cs +++ b/StackInjector/Core/Cloning/IClonedCore.cs @@ -33,7 +33,7 @@ public interface IClonedCore /// type of output elements /// action to perform on elements /// the new wrapper - IAsyncStackWrapper ToGenericAsync ( AsyncStackDigest digest ); + IAsyncStackWrapper ToGenericAsync ( AsyncStackDigest digest ); } diff --git a/StackInjector/Core/IAsyncStackWrapperCore.cs b/StackInjector/Core/IAsyncStackWrapperCore.cs index ee32476..3acb7fe 100644 --- a/StackInjector/Core/IAsyncStackWrapperCore.cs +++ b/StackInjector/Core/IAsyncStackWrapperCore.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Text; using System.Threading; using System.Threading.Tasks; diff --git a/StackInjector/Core/StackWrapperCore.cs b/StackInjector/Core/StackWrapperCore.cs index 0580330..4d0fac1 100644 --- a/StackInjector/Core/StackWrapperCore.cs +++ b/StackInjector/Core/StackWrapperCore.cs @@ -35,6 +35,6 @@ public IClonedCore CloneCore ( StackWrapperSettings settings = null ) public abstract void Dispose (); - + } } diff --git a/StackInjector/Core/WrapperCore.injection.cs b/StackInjector/Core/WrapperCore.injection.cs index 39ef865..a1809f6 100644 --- a/StackInjector/Core/WrapperCore.injection.cs +++ b/StackInjector/Core/WrapperCore.injection.cs @@ -31,7 +31,7 @@ internal IEnumerable InjectServicesInto ( object instance ) #region injection methods - private void InjectFields( Type type, object instance, ref List instantiated ) + private void InjectFields ( Type type, object instance, ref List instantiated ) { var fields = type diff --git a/StackInjector/Core/WrapperCore.logic.cs b/StackInjector/Core/WrapperCore.logic.cs index 6c24e8a..b383443 100644 --- a/StackInjector/Core/WrapperCore.logic.cs +++ b/StackInjector/Core/WrapperCore.logic.cs @@ -43,7 +43,7 @@ internal T GetEntryPoint () return (T)this .instances - .OfType( this.entryPoint ) + .OfType(this.entryPoint) .First(); } } diff --git a/StackInjector/Injector.cs b/StackInjector/Injector.cs index a5fce70..a230d20 100644 --- a/StackInjector/Injector.cs +++ b/StackInjector/Injector.cs @@ -1,5 +1,4 @@ -using StackInjector.Behaviours; -using StackInjector.Core; +using StackInjector.Core; using StackInjector.Exceptions; using StackInjector.Settings; using StackInjector.Wrappers; @@ -59,7 +58,7 @@ public static IAsyncStackWrapper AsyncFrom ( StackWrapperSettings settings = { if( settings == null ) settings = StackWrapperSettings.Default; - + // create a new async stack wrapper var core = new WrapperCore( settings ) @@ -85,8 +84,8 @@ public static IAsyncStackWrapper AsyncFrom ( StackWrapperSettings settings = /// delegate used to call the relative method to perform on submitted items /// the settings to use with this object. If null, use default. /// - public static IAsyncStackWrapper AsyncFrom - ( + public static IAsyncStackWrapper AsyncFrom + ( AsyncStackDigest digest, StackWrapperSettings settings = null ) diff --git a/StackInjector/Settings/StackWrapperSettings.cs b/StackInjector/Settings/StackWrapperSettings.cs index ae088b1..7e9241a 100644 --- a/StackInjector/Settings/StackWrapperSettings.cs +++ b/StackInjector/Settings/StackWrapperSettings.cs @@ -30,7 +30,7 @@ public sealed partial class StackWrapperSettings // async management internal AsyncWaitingMethod asyncWaitingMethod; internal int asyncWaitTime; - + #endregion diff --git a/StackInjector/Wrappers/AsyncStackWrapper.cs b/StackInjector/Wrappers/AsyncStackWrapper.cs index 2bddc48..f64f915 100644 --- a/StackInjector/Wrappers/AsyncStackWrapper.cs +++ b/StackInjector/Wrappers/AsyncStackWrapper.cs @@ -1,14 +1,11 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; +using System.Linq; using StackInjector.Attributes; using StackInjector.Core; namespace StackInjector.Wrappers { [Service(DoNotServeMembers = true, Version = 2.0)] - internal partial class AsyncStackWrapper : AsyncStackWrapperCore, IAsyncStackWrapper + internal partial class AsyncStackWrapper : AsyncStackWrapperCore, IAsyncStackWrapper { /// @@ -20,7 +17,7 @@ internal AsyncStackWrapper ( WrapperCore core ) : base(core, typeof(AsyncStackWr public void Submit ( object item ) { - var task = + var task = this .Core .GetEntryPoint() diff --git a/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs b/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs index 11e33ad..8448fe1 100644 --- a/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs +++ b/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Linq; using StackInjector.Attributes; using StackInjector.Core; diff --git a/StackInjector/Wrappers/Generic/IAsyncStackWrapper.cs b/StackInjector/Wrappers/Generic/IAsyncStackWrapper.cs index ac1f857..fd0d746 100644 --- a/StackInjector/Wrappers/Generic/IAsyncStackWrapper.cs +++ b/StackInjector/Wrappers/Generic/IAsyncStackWrapper.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using StackInjector.Core; @@ -18,11 +16,11 @@ namespace StackInjector.Wrappers.Generic /// the item to elaborate /// the cancellation token used to cancel the task /// a task rappresenting the current job - public delegate Task AsyncStackDigest - ( + public delegate Task AsyncStackDigest + ( TEntry instance, - TIn item, - CancellationToken cancellationToken + TIn item, + CancellationToken cancellationToken ); diff --git a/StackInjector/Wrappers/IAsyncStackWrapper.cs b/StackInjector/Wrappers/IAsyncStackWrapper.cs index c6373ef..52f9232 100644 --- a/StackInjector/Wrappers/IAsyncStackWrapper.cs +++ b/StackInjector/Wrappers/IAsyncStackWrapper.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Threading; +using System.Collections.Generic; using StackInjector.Core; namespace StackInjector.Wrappers From 7c507e6ceb40020bd6db2f89e2d7e5b4098c5935 Mon Sep 17 00:00:00 2001 From: JacopoWolf Date: Sat, 16 May 2020 18:20:08 +0200 Subject: [PATCH 11/13] Update AsyncStackWrapperCore.logic.cs --- StackInjector/Core/AsyncStackWrapperCore.logic.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/StackInjector/Core/AsyncStackWrapperCore.logic.cs b/StackInjector/Core/AsyncStackWrapperCore.logic.cs index 86735e3..3121759 100644 --- a/StackInjector/Core/AsyncStackWrapperCore.logic.cs +++ b/StackInjector/Core/AsyncStackWrapperCore.logic.cs @@ -81,6 +81,7 @@ Task listAwaiter () var list = listAwaiter(); var timeout = Task.Delay( this.Settings.asyncWaitTime ); + // if the timeout elapses first, then stop waiting return (await Task.WhenAny(list, timeout).ConfigureAwait(true)) == timeout; } } From aa850d7e4f51fac077e409789a722771b3357d0b Mon Sep 17 00:00:00 2001 From: JacopoWolf Date: Mon, 18 May 2020 00:11:13 +0200 Subject: [PATCH 12/13] Added option to modify serving resolves #52 --- StackInjector/Attributes/ServiceAttribute.cs | 7 +-- StackInjector/Core/WrapperCore.injection.cs | 44 ++++++++++++------- StackInjector/Injector.cs | 2 +- StackInjector/Injector.defaults.cs | 33 ++++++++++++++ StackInjector/Settings/ServingMethods.cs | 34 ++++++++++++++ StackInjector/Wrappers/AsyncStackWrapper.cs | 3 +- .../Wrappers/Generic/AsyncStackWrapper.cs | 3 +- StackInjector/Wrappers/StackWrapper.cs | 3 +- .../Services/ThingsGenerator.cs | 4 +- 9 files changed, 108 insertions(+), 25 deletions(-) create mode 100644 StackInjector/Injector.defaults.cs create mode 100644 StackInjector/Settings/ServingMethods.cs diff --git a/StackInjector/Attributes/ServiceAttribute.cs b/StackInjector/Attributes/ServiceAttribute.cs index 9568233..bdb6d52 100644 --- a/StackInjector/Attributes/ServiceAttribute.cs +++ b/StackInjector/Attributes/ServiceAttribute.cs @@ -1,4 +1,5 @@ using System; +using StackInjector.Settings; namespace StackInjector.Attributes { @@ -22,9 +23,9 @@ public sealed class ServiceAttribute : Attribute public bool ReuseInstance { get; set; } = false; /// - /// if set to true, members of this object will not be served even if marked as such + /// how properties and fields of this service should be served /// - public bool DoNotServeMembers { get; set; } = false; - + public ServingMethods Serving { get; set; } = Injector.Defaults.ServingMethod; } + } diff --git a/StackInjector/Core/WrapperCore.injection.cs b/StackInjector/Core/WrapperCore.injection.cs index a1809f6..3002119 100644 --- a/StackInjector/Core/WrapperCore.injection.cs +++ b/StackInjector/Core/WrapperCore.injection.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using StackInjector.Attributes; +using StackInjector.Settings; namespace StackInjector.Core { @@ -17,26 +18,37 @@ internal IEnumerable InjectServicesInto ( object instance ) { var instantiated = new List(); var type = instance.GetType(); + var serving = type.GetCustomAttribute()?.Serving ?? Injector.Defaults.ServingMethod; - // setting for ignoring service of members. Defined in [Service] attribute - if( type.GetCustomAttribute()?.DoNotServeMembers ?? false ) + // don't waste time serving if not necessary + if( serving == ServingMethods.DoNotServe ) return instantiated; - this.InjectFields(type, instance, ref instantiated); - this.InjectProperties(type, instance, ref instantiated); + // if false avoids going though the properties/fields list a second time to filter + var onlyWithAttrib = serving.HasFlag(ServingMethods.Strict); + + + if ( serving.HasFlag(ServingMethods.Fields) ) + this.InjectFields(type, instance, ref instantiated, onlyWithAttrib); + + if ( serving.HasFlag(ServingMethods.Properties) ) + this.InjectProperties(type, instance, ref instantiated, onlyWithAttrib); return instantiated; } + + #region injection methods - private void InjectFields ( Type type, object instance, ref List instantiated ) + private void InjectFields ( Type type, object instance, ref List instantiated, bool hasAttribute ) { - var fields = - type - .GetFields( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ) - .Where( field => field.GetCustomAttribute() != null ); + IEnumerable fields = + type.GetFields( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ); + + if ( hasAttribute ) + fields = fields.Where( field => field.GetCustomAttribute() != null ); foreach( var serviceField in fields ) { @@ -48,12 +60,14 @@ private void InjectFields ( Type type, object instance, ref List instant } } - private void InjectProperties ( Type type, object instance, ref List instantiated ) + + private void InjectProperties ( Type type, object instance, ref List instantiated, bool hasAttribute ) { - var properties = - type - .GetProperties( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ) - .Where( property => property.GetCustomAttribute() != null ); + IEnumerable properties = + type.GetProperties( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ); + + if ( hasAttribute ) + properties = properties.Where( property => property.GetCustomAttribute() != null ); foreach( var propertyField in properties ) { @@ -68,4 +82,4 @@ private void InjectProperties ( Type type, object instance, ref List ins #endregion } -} +} \ No newline at end of file diff --git a/StackInjector/Injector.cs b/StackInjector/Injector.cs index a230d20..a402f02 100644 --- a/StackInjector/Injector.cs +++ b/StackInjector/Injector.cs @@ -12,7 +12,7 @@ namespace StackInjector /// If you want to clone an existing structure, see /// /// - public static class Injector + public static partial class Injector { //todo SingleInstanceHolder should depend upon a setting diff --git a/StackInjector/Injector.defaults.cs b/StackInjector/Injector.defaults.cs new file mode 100644 index 0000000..4fd76c8 --- /dev/null +++ b/StackInjector/Injector.defaults.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; +using StackInjector.Attributes; +using StackInjector.Settings; +using StackInjector.Wrappers; + +namespace StackInjector +{ + public static partial class Injector + { + /// + /// Static class for default settings. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1034", Justification = "This is more ordered")] + public static class Defaults + { + // the const keyword allows usage in attributes + + /// + /// The default serving method + /// + public const ServingMethods ServingMethod = + ( ServingMethods.Fields | ServingMethods.Properties | ServingMethods.Strict); + + /// + /// Serve every field and property ignoring if they have the + /// + public const ServingMethods ServeAll = + ( ServingMethods.Fields | ServingMethods.Properties ); + } + } +} diff --git a/StackInjector/Settings/ServingMethods.cs b/StackInjector/Settings/ServingMethods.cs new file mode 100644 index 0000000..fd5dcad --- /dev/null +++ b/StackInjector/Settings/ServingMethods.cs @@ -0,0 +1,34 @@ +using System; +using StackInjector.Attributes; + +namespace StackInjector.Settings +{ + /// + /// + /// + [Flags] + public enum ServingMethods + { + /// + /// empty servicing method + /// + DoNotServe = 0, + + /// + /// Serve only to those properties or fields marked with . + /// If not set, serve everything + /// + Strict = 0b1000, + + /// + /// Allow serving to fields + /// + Fields = 0b0001, + + /// + /// Allow serving to properties + /// + Properties = 0b0010 + } + +} diff --git a/StackInjector/Wrappers/AsyncStackWrapper.cs b/StackInjector/Wrappers/AsyncStackWrapper.cs index f64f915..80decf1 100644 --- a/StackInjector/Wrappers/AsyncStackWrapper.cs +++ b/StackInjector/Wrappers/AsyncStackWrapper.cs @@ -1,10 +1,11 @@ using System.Linq; using StackInjector.Attributes; using StackInjector.Core; +using StackInjector.Settings; namespace StackInjector.Wrappers { - [Service(DoNotServeMembers = true, Version = 2.0)] + [Service(Version = 2.0, Serving = ServingMethods.DoNotServe)] internal partial class AsyncStackWrapper : AsyncStackWrapperCore, IAsyncStackWrapper { diff --git a/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs b/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs index 8448fe1..b5dc278 100644 --- a/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs +++ b/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs @@ -1,10 +1,11 @@ using System.Linq; using StackInjector.Attributes; using StackInjector.Core; +using StackInjector.Settings; namespace StackInjector.Wrappers.Generic { - [Service(Version = 2.1, DoNotServeMembers = true)] + [Service(Version = 2.1, Serving = ServingMethods.DoNotServe)] internal class AsyncStackWrapper : AsyncStackWrapperCore, IAsyncStackWrapper { diff --git a/StackInjector/Wrappers/StackWrapper.cs b/StackInjector/Wrappers/StackWrapper.cs index e5cb148..5558707 100644 --- a/StackInjector/Wrappers/StackWrapper.cs +++ b/StackInjector/Wrappers/StackWrapper.cs @@ -1,10 +1,11 @@ using System.Linq; using StackInjector.Attributes; using StackInjector.Core; +using StackInjector.Settings; namespace StackInjector.Wrappers { - [Service(Version = 1.0, DoNotServeMembers = true)] + [Service(Version = 1.0, Serving = ServingMethods.DoNotServe)] internal class StackWrapper : AsyncStackWrapperCore, IStackWrapper { diff --git a/tests/StackInjector.TEST.SimpleStack1/Services/ThingsGenerator.cs b/tests/StackInjector.TEST.SimpleStack1/Services/ThingsGenerator.cs index d75a958..ff32e5b 100644 --- a/tests/StackInjector.TEST.SimpleStack1/Services/ThingsGenerator.cs +++ b/tests/StackInjector.TEST.SimpleStack1/Services/ThingsGenerator.cs @@ -9,13 +9,11 @@ internal interface IThingsGenerator : IStackEntryPoint string GenerateThing (); } - [Service] + [Service(Serving = Injector.Defaults.ServeAll)] internal class SimpleThingsGenerator : IThingsGenerator { - [Served] private SimpleThingsFilter ThingsFilter { get; set; } - [Served] private IThingsConsumer ThingsConsumer { get; set; } From dd75beebf73aceae34a2ae7aeb5bb10260446999 Mon Sep 17 00:00:00 2001 From: JacopoWolf Date: Mon, 18 May 2020 18:07:04 +0200 Subject: [PATCH 13/13] cleanup - renamed WrapperCore to InjectionCore - correctly renamed StackWrapperCore - updated documentation --- StackInjector/Attributes/ServedAttribute.cs | 6 +++--- StackInjector/Attributes/ServiceAttribute.cs | 12 ++---------- StackInjector/Behaviours/IInstancesHolder.cs | 1 + StackInjector/Behaviours/SingleInstanceHolder.cs | 3 +-- StackInjector/Core/AsyncStackWrapperCore.cs | 8 ++++---- StackInjector/Core/AsyncStackWrapperCore.logic.cs | 2 +- StackInjector/Core/Cloning/ClonedCore.cs | 6 +++--- StackInjector/Core/Cloning/IClonedCore.cs | 2 +- .../Core/{WrapperCore.cs => InjectionCore.cs} | 4 ++-- ...ore.injection.cs => InjectionCore.injection.cs} | 14 +++++++------- ...antiation.cs => InjectionCore.instantiation.cs} | 2 +- ...WrapperCore.logic.cs => InjectionCore.logic.cs} | 2 +- ...e.reflection.cs => InjectionCore.reflection.cs} | 2 +- ...e.versioning.cs => InjectionCore.versioning.cs} | 2 +- StackInjector/Core/StackWrapperCore.cs | 11 +++++++---- StackInjector/Injector.cs | 6 +++--- StackInjector/Injector.defaults.cs | 6 +----- StackInjector/Settings/AsyncWaitingMethod.cs | 6 +++--- .../Settings/StackWrapperSettings.configuration.cs | 2 +- StackInjector/Settings/StackWrapperSettings.cs | 5 +++-- StackInjector/Wrappers/AsyncStackWrapper.cs | 2 +- .../Wrappers/Generic/AsyncStackWrapper.cs | 2 +- StackInjector/Wrappers/StackWrapper.cs | 4 ++-- tests/StackInjector.TEST.Async/TestProgram.cs | 2 +- 24 files changed, 52 insertions(+), 60 deletions(-) rename StackInjector/Core/{WrapperCore.cs => InjectionCore.cs} (89%) rename StackInjector/Core/{WrapperCore.injection.cs => InjectionCore.injection.cs} (86%) rename StackInjector/Core/{WrapperCore.instantiation.cs => InjectionCore.instantiation.cs} (98%) rename StackInjector/Core/{WrapperCore.logic.cs => InjectionCore.logic.cs} (96%) rename StackInjector/Core/{WrapperCore.reflection.cs => InjectionCore.reflection.cs} (98%) rename StackInjector/Core/{WrapperCore.versioning.cs => InjectionCore.versioning.cs} (98%) diff --git a/StackInjector/Attributes/ServedAttribute.cs b/StackInjector/Attributes/ServedAttribute.cs index 6b3094a..f501452 100644 --- a/StackInjector/Attributes/ServedAttribute.cs +++ b/StackInjector/Attributes/ServedAttribute.cs @@ -15,12 +15,12 @@ public sealed class ServedAttribute : Attribute /// public double TargetVersion { get; set; } = 0.0; - /// - /// targetting version method + /// How the specified TargetVersion should be found. + /// could be overriden by /// public ServedVersionTargetingMethod? TargetingMethod { get; set; } = null; } -} +} \ No newline at end of file diff --git a/StackInjector/Attributes/ServiceAttribute.cs b/StackInjector/Attributes/ServiceAttribute.cs index bdb6d52..ae83adc 100644 --- a/StackInjector/Attributes/ServiceAttribute.cs +++ b/StackInjector/Attributes/ServiceAttribute.cs @@ -9,23 +9,15 @@ namespace StackInjector.Attributes [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] public sealed class ServiceAttribute : Attribute { - /// /// The version of this service implementation /// public double Version { get; set; } = -0.0; - - /// - /// Indicates if the framework should use only one instance of this service across all clients. - /// Might be ignored by the settings. - /// - public bool ReuseInstance { get; set; } = false; - /// - /// how properties and fields of this service should be served + /// How properties and fields of this service should be served /// public ServingMethods Serving { get; set; } = Injector.Defaults.ServingMethod; } -} +} \ No newline at end of file diff --git a/StackInjector/Behaviours/IInstancesHolder.cs b/StackInjector/Behaviours/IInstancesHolder.cs index c5b1e38..3c1e544 100644 --- a/StackInjector/Behaviours/IInstancesHolder.cs +++ b/StackInjector/Behaviours/IInstancesHolder.cs @@ -3,6 +3,7 @@ namespace StackInjector.Behaviours { + //? should this be documented internally internal interface IInstancesHolder { IEnumerable OfType ( Type type ); diff --git a/StackInjector/Behaviours/SingleInstanceHolder.cs b/StackInjector/Behaviours/SingleInstanceHolder.cs index 2055d4b..2e458c7 100644 --- a/StackInjector/Behaviours/SingleInstanceHolder.cs +++ b/StackInjector/Behaviours/SingleInstanceHolder.cs @@ -34,7 +34,6 @@ public bool ContainsType ( Type type ) public IEnumerable GetAllTypes () => this.Keys; - - } + } \ No newline at end of file diff --git a/StackInjector/Core/AsyncStackWrapperCore.cs b/StackInjector/Core/AsyncStackWrapperCore.cs index 13b6d14..c044a14 100644 --- a/StackInjector/Core/AsyncStackWrapperCore.cs +++ b/StackInjector/Core/AsyncStackWrapperCore.cs @@ -5,7 +5,7 @@ namespace StackInjector.Core { - internal abstract partial class AsyncStackWrapperCore : AsyncStackWrapperCore, IAsyncStackWrapperCore + internal abstract partial class AsyncStackWrapperCore : StackWrapperCore, IAsyncStackWrapperCore { // used to cancel everything @@ -25,7 +25,7 @@ public CancellationToken PendingTasksCancellationToken protected internal LinkedList> tasks = new LinkedList>(); - internal AsyncStackWrapperCore ( WrapperCore core, Type toRegister ) : base(core, toRegister) + internal AsyncStackWrapperCore ( InjectionCore core, Type toRegister ) : base(core, toRegister) { // register an event that in case the list is empty, release the empty event listener. this.cancelPendingTasksSource.Token.Register(this.ReleaseListAwaiter); @@ -63,6 +63,6 @@ public override void Dispose () } #endregion - } -} + +} \ No newline at end of file diff --git a/StackInjector/Core/AsyncStackWrapperCore.logic.cs b/StackInjector/Core/AsyncStackWrapperCore.logic.cs index 3121759..c37cbce 100644 --- a/StackInjector/Core/AsyncStackWrapperCore.logic.cs +++ b/StackInjector/Core/AsyncStackWrapperCore.logic.cs @@ -77,7 +77,7 @@ Task listAwaiter () return false; - case AsyncWaitingMethod.WaitTimeout: + case AsyncWaitingMethod.Timeout: var list = listAwaiter(); var timeout = Task.Delay( this.Settings.asyncWaitTime ); diff --git a/StackInjector/Core/Cloning/ClonedCore.cs b/StackInjector/Core/Cloning/ClonedCore.cs index a36a22d..1882af9 100644 --- a/StackInjector/Core/Cloning/ClonedCore.cs +++ b/StackInjector/Core/Cloning/ClonedCore.cs @@ -6,9 +6,9 @@ namespace StackInjector.Core.Cloning internal class ClonedCore : IClonedCore { - private readonly WrapperCore clonedCore; + private readonly InjectionCore clonedCore; - internal ClonedCore ( WrapperCore clonedCore ) + internal ClonedCore ( InjectionCore clonedCore ) => this.clonedCore = clonedCore; @@ -23,7 +23,7 @@ public IAsyncStackWrapper ToAsyncWrapper () where T : IAsyncStackEntryPoint return wrapper; } - public IAsyncStackWrapper ToGenericAsync ( AsyncStackDigest digest ) + public IAsyncStackWrapper ToAsyncWrapper ( AsyncStackDigest digest ) { var wrapper = new AsyncStackWrapper( this.clonedCore ); diff --git a/StackInjector/Core/Cloning/IClonedCore.cs b/StackInjector/Core/Cloning/IClonedCore.cs index b79efbe..7f2eda7 100644 --- a/StackInjector/Core/Cloning/IClonedCore.cs +++ b/StackInjector/Core/Cloning/IClonedCore.cs @@ -33,7 +33,7 @@ public interface IClonedCore /// type of output elements /// action to perform on elements /// the new wrapper - IAsyncStackWrapper ToGenericAsync ( AsyncStackDigest digest ); + IAsyncStackWrapper ToAsyncWrapper ( AsyncStackDigest digest ); } diff --git a/StackInjector/Core/WrapperCore.cs b/StackInjector/Core/InjectionCore.cs similarity index 89% rename from StackInjector/Core/WrapperCore.cs rename to StackInjector/Core/InjectionCore.cs index fd25eb0..3c81a64 100644 --- a/StackInjector/Core/WrapperCore.cs +++ b/StackInjector/Core/InjectionCore.cs @@ -9,7 +9,7 @@ namespace StackInjector.Core /// The core common logic of every stack wrapper. /// The jobs of this class are reflection, versioning, instantiation, and injection. /// - internal partial class WrapperCore + internal partial class InjectionCore { // entry point object of this core internal Type entryPoint; @@ -24,7 +24,7 @@ internal partial class WrapperCore internal readonly List instancesDiff; - internal WrapperCore ( StackWrapperSettings settings ) + internal InjectionCore ( StackWrapperSettings settings ) { this.settings = settings; diff --git a/StackInjector/Core/WrapperCore.injection.cs b/StackInjector/Core/InjectionCore.injection.cs similarity index 86% rename from StackInjector/Core/WrapperCore.injection.cs rename to StackInjector/Core/InjectionCore.injection.cs index 3002119..1f25397 100644 --- a/StackInjector/Core/WrapperCore.injection.cs +++ b/StackInjector/Core/InjectionCore.injection.cs @@ -7,7 +7,7 @@ namespace StackInjector.Core { - internal partial class WrapperCore + internal partial class InjectionCore { /// /// Injects services into the specified instance, instantiating them on necessity. @@ -28,10 +28,10 @@ internal IEnumerable InjectServicesInto ( object instance ) var onlyWithAttrib = serving.HasFlag(ServingMethods.Strict); - if ( serving.HasFlag(ServingMethods.Fields) ) + if( serving.HasFlag(ServingMethods.Fields) ) this.InjectFields(type, instance, ref instantiated, onlyWithAttrib); - if ( serving.HasFlag(ServingMethods.Properties) ) + if( serving.HasFlag(ServingMethods.Properties) ) this.InjectProperties(type, instance, ref instantiated, onlyWithAttrib); @@ -47,8 +47,8 @@ private void InjectFields ( Type type, object instance, ref List instant IEnumerable fields = type.GetFields( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ); - if ( hasAttribute ) - fields = fields.Where( field => field.GetCustomAttribute() != null ); + if( hasAttribute ) + fields = fields.Where(field => field.GetCustomAttribute() != null); foreach( var serviceField in fields ) { @@ -66,8 +66,8 @@ private void InjectProperties ( Type type, object instance, ref List ins IEnumerable properties = type.GetProperties( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance ); - if ( hasAttribute ) - properties = properties.Where( property => property.GetCustomAttribute() != null ); + if( hasAttribute ) + properties = properties.Where(property => property.GetCustomAttribute() != null); foreach( var propertyField in properties ) { diff --git a/StackInjector/Core/WrapperCore.instantiation.cs b/StackInjector/Core/InjectionCore.instantiation.cs similarity index 98% rename from StackInjector/Core/WrapperCore.instantiation.cs rename to StackInjector/Core/InjectionCore.instantiation.cs index 96e1be8..ddb9ec5 100644 --- a/StackInjector/Core/WrapperCore.instantiation.cs +++ b/StackInjector/Core/InjectionCore.instantiation.cs @@ -6,7 +6,7 @@ namespace StackInjector.Core { - internal partial class WrapperCore + internal partial class InjectionCore { /// /// Instantiates the specified [Served] type diff --git a/StackInjector/Core/WrapperCore.logic.cs b/StackInjector/Core/InjectionCore.logic.cs similarity index 96% rename from StackInjector/Core/WrapperCore.logic.cs rename to StackInjector/Core/InjectionCore.logic.cs index b383443..90a5c92 100644 --- a/StackInjector/Core/WrapperCore.logic.cs +++ b/StackInjector/Core/InjectionCore.logic.cs @@ -3,7 +3,7 @@ namespace StackInjector.Core { - internal partial class WrapperCore + internal partial class InjectionCore { internal void ServeAll () diff --git a/StackInjector/Core/WrapperCore.reflection.cs b/StackInjector/Core/InjectionCore.reflection.cs similarity index 98% rename from StackInjector/Core/WrapperCore.reflection.cs rename to StackInjector/Core/InjectionCore.reflection.cs index aca2438..fef971e 100644 --- a/StackInjector/Core/WrapperCore.reflection.cs +++ b/StackInjector/Core/InjectionCore.reflection.cs @@ -6,7 +6,7 @@ namespace StackInjector.Core { - internal partial class WrapperCore + internal partial class InjectionCore { /// /// Returns type if it's a [Service] class, diff --git a/StackInjector/Core/WrapperCore.versioning.cs b/StackInjector/Core/InjectionCore.versioning.cs similarity index 98% rename from StackInjector/Core/WrapperCore.versioning.cs rename to StackInjector/Core/InjectionCore.versioning.cs index 6e320f6..dacb7ee 100644 --- a/StackInjector/Core/WrapperCore.versioning.cs +++ b/StackInjector/Core/InjectionCore.versioning.cs @@ -6,7 +6,7 @@ namespace StackInjector.Core { - internal partial class WrapperCore + internal partial class InjectionCore { internal Type Version diff --git a/StackInjector/Core/StackWrapperCore.cs b/StackInjector/Core/StackWrapperCore.cs index 4d0fac1..5994958 100644 --- a/StackInjector/Core/StackWrapperCore.cs +++ b/StackInjector/Core/StackWrapperCore.cs @@ -4,16 +4,19 @@ namespace StackInjector.Core { - internal abstract class AsyncStackWrapperCore : IStackWrapperCore + /// + /// Base implementation for stack wrappers + /// + internal abstract class StackWrapperCore : IStackWrapperCore { public ref readonly StackWrapperSettings Settings => ref this.Core.settings; - private protected readonly WrapperCore Core; + private protected readonly InjectionCore Core; - public AsyncStackWrapperCore ( WrapperCore core, Type toRegister ) + public StackWrapperCore ( InjectionCore core, Type toRegister ) { this.Core = core; @@ -25,7 +28,7 @@ public AsyncStackWrapperCore ( WrapperCore core, Type toRegister ) public IClonedCore CloneCore ( StackWrapperSettings settings = null ) { - var clonedCore = new WrapperCore( settings ?? this.Core.settings ) + var clonedCore = new InjectionCore( settings ?? this.Core.settings ) { instances = this.Core.instances }; diff --git a/StackInjector/Injector.cs b/StackInjector/Injector.cs index a402f02..e123796 100644 --- a/StackInjector/Injector.cs +++ b/StackInjector/Injector.cs @@ -31,7 +31,7 @@ public static IStackWrapper From ( StackWrapperSettings settings = null ) whe settings = StackWrapperSettings.Default; // create a new stackwrapper with the specified settings - var core = new WrapperCore( settings ) + var core = new InjectionCore( settings ) { entryPoint = typeof(T) }; @@ -61,7 +61,7 @@ public static IAsyncStackWrapper AsyncFrom ( StackWrapperSettings settings = // create a new async stack wrapper - var core = new WrapperCore( settings ) + var core = new InjectionCore( settings ) { entryPoint = typeof(T) }; @@ -94,7 +94,7 @@ public static IAsyncStackWrapper AsyncFrom settings = StackWrapperSettings.Default; // create a new generic async wrapper - var core = new WrapperCore( settings ) + var core = new InjectionCore( settings ) { entryPoint = typeof(TEntry) }; diff --git a/StackInjector/Injector.defaults.cs b/StackInjector/Injector.defaults.cs index 4fd76c8..6868b9c 100644 --- a/StackInjector/Injector.defaults.cs +++ b/StackInjector/Injector.defaults.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Text; -using StackInjector.Attributes; +using StackInjector.Attributes; using StackInjector.Settings; -using StackInjector.Wrappers; namespace StackInjector { diff --git a/StackInjector/Settings/AsyncWaitingMethod.cs b/StackInjector/Settings/AsyncWaitingMethod.cs index 09f7cb1..5b4075d 100644 --- a/StackInjector/Settings/AsyncWaitingMethod.cs +++ b/StackInjector/Settings/AsyncWaitingMethod.cs @@ -19,10 +19,10 @@ public enum AsyncWaitingMethod Wait, /// - /// don't immediately exit the loop, but rather wait a certain amount of time before exiting the loop + /// don't immediately exit the loop, but rather wait a certain amount of time for + /// new tasks to be submitted tobefore exiting the loop /// - WaitTimeout - + Timeout } } \ No newline at end of file diff --git a/StackInjector/Settings/StackWrapperSettings.configuration.cs b/StackInjector/Settings/StackWrapperSettings.configuration.cs index 1c42f8b..5540c8e 100644 --- a/StackInjector/Settings/StackWrapperSettings.configuration.cs +++ b/StackInjector/Settings/StackWrapperSettings.configuration.cs @@ -90,7 +90,7 @@ public StackWrapperSettings VersioningMethod ( ServedVersionTargetingMethod targ /// has no more pending tasks to execute /// /// the new waiting method - /// if is set, this will be max time to wait + /// if is set, this will be max time to wait /// the modified settings public StackWrapperSettings WhenNoMoreTasks ( AsyncWaitingMethod waitingMethod, int waitTime = 1000 ) { diff --git a/StackInjector/Settings/StackWrapperSettings.cs b/StackInjector/Settings/StackWrapperSettings.cs index 7e9241a..76473ea 100644 --- a/StackInjector/Settings/StackWrapperSettings.cs +++ b/StackInjector/Settings/StackWrapperSettings.cs @@ -31,11 +31,12 @@ public sealed partial class StackWrapperSettings internal AsyncWaitingMethod asyncWaitingMethod; internal int asyncWaitTime; - #endregion + private StackWrapperSettings () { } + /// /// generates a new empty . Nothing is set. /// High chance a NullReference might be thrown if not treated correctly. @@ -64,4 +65,4 @@ public static StackWrapperSettings Default //? maybe add a DefaultInner for nested wrappers } -} +} \ No newline at end of file diff --git a/StackInjector/Wrappers/AsyncStackWrapper.cs b/StackInjector/Wrappers/AsyncStackWrapper.cs index 80decf1..758331b 100644 --- a/StackInjector/Wrappers/AsyncStackWrapper.cs +++ b/StackInjector/Wrappers/AsyncStackWrapper.cs @@ -12,7 +12,7 @@ internal partial class AsyncStackWrapper : AsyncStackWrapperCore, IAsync /// /// create a new AsyncStackWrapper /// - internal AsyncStackWrapper ( WrapperCore core ) : base(core, typeof(AsyncStackWrapper)) + internal AsyncStackWrapper ( InjectionCore core ) : base(core, typeof(AsyncStackWrapper)) { } diff --git a/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs b/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs index b5dc278..00e6b2a 100644 --- a/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs +++ b/StackInjector/Wrappers/Generic/AsyncStackWrapper.cs @@ -11,7 +11,7 @@ internal class AsyncStackWrapper : AsyncStackWrapperCore StackDigest { get; internal set; } - public AsyncStackWrapper ( WrapperCore core ) : base(core, typeof(AsyncStackWrapper)) + public AsyncStackWrapper ( InjectionCore core ) : base(core, typeof(AsyncStackWrapper)) { } public void Submit ( TIn item ) diff --git a/StackInjector/Wrappers/StackWrapper.cs b/StackInjector/Wrappers/StackWrapper.cs index 5558707..a5a69c5 100644 --- a/StackInjector/Wrappers/StackWrapper.cs +++ b/StackInjector/Wrappers/StackWrapper.cs @@ -6,11 +6,11 @@ namespace StackInjector.Wrappers { [Service(Version = 1.0, Serving = ServingMethods.DoNotServe)] - internal class StackWrapper : AsyncStackWrapperCore, IStackWrapper + internal class StackWrapper : StackWrapperCore, IStackWrapper { - internal StackWrapper ( WrapperCore core ) : base(core, typeof(StackWrapper)) + internal StackWrapper ( InjectionCore core ) : base(core, typeof(StackWrapper)) { } diff --git a/tests/StackInjector.TEST.Async/TestProgram.cs b/tests/StackInjector.TEST.Async/TestProgram.cs index cd71f1c..894525b 100644 --- a/tests/StackInjector.TEST.Async/TestProgram.cs +++ b/tests/StackInjector.TEST.Async/TestProgram.cs @@ -19,7 +19,7 @@ public async Task TestAsync () // wait for a maximum of 500 milliseconds var settings = StackWrapperSettings.Default - .WhenNoMoreTasks(AsyncWaitingMethod.WaitTimeout, 500 ); + .WhenNoMoreTasks(AsyncWaitingMethod.Timeout, 500 ); using var asyncwrapper = Injector.AsyncFrom( settings );