diff --git a/Adapters/V4/Create.cs b/Adapters/V4/Create.cs
new file mode 100644
index 0000000..8ea60fa
--- /dev/null
+++ b/Adapters/V4/Create.cs
@@ -0,0 +1,10 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Jobs;
+
+namespace Unity.v4
+{
+ [SimpleJob(RuntimeMoniker.Net462)]
+ public class Create : Benchmarks.Create
+ {
+ }
+}
diff --git a/Adapters/V4/Unity.v4.csproj b/Adapters/V4/Unity.v4.csproj
index fe8bcb4..407245b 100644
--- a/Adapters/V4/Unity.v4.csproj
+++ b/Adapters/V4/Unity.v4.csproj
@@ -7,6 +7,7 @@
net462
+
diff --git a/Adapters/V4/UnityAdapterV4.cs b/Adapters/V4/UnityAdapterV4.cs
index 7525e7d..a58d142 100644
--- a/Adapters/V4/UnityAdapterV4.cs
+++ b/Adapters/V4/UnityAdapterV4.cs
@@ -1,12 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Unity.v4
+namespace Unity.v4
{
- public class UnityAdapterV4
+ // Marker type for Unity Adapter v4
+ public sealed class UnityAdapterV4
{
}
}
diff --git a/Adapters/V4/UnityContainerAPI.cs b/Adapters/V4/UnityContainerAPI.cs
deleted file mode 100644
index 839c037..0000000
--- a/Adapters/V4/UnityContainerAPI.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Unity.Benchmarks;
-
-namespace Unity.v4
-{
- [ShortRunJob(RuntimeMoniker.Net462)]
- public class UnityContainerAPI : ContainerAPI
- {
- }
-}
diff --git a/Adapters/V4/UnityRegisterAPI.cs b/Adapters/V4/UnityRegisterAPI.cs
deleted file mode 100644
index f58f399..0000000
--- a/Adapters/V4/UnityRegisterAPI.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Unity.Benchmarks;
-
-namespace Unity.v4
-{
- [ShortRunJob(RuntimeMoniker.Net462)]
- public class UnityRegister : RegisterAPI
- {
- }
-}
diff --git a/Adapters/V4/UnityResolution.cs b/Adapters/V4/UnityResolution.cs
index f04c3a0..06c138d 100644
--- a/Adapters/V4/UnityResolution.cs
+++ b/Adapters/V4/UnityResolution.cs
@@ -5,7 +5,7 @@
namespace Unity.v4
{
[SimpleJob(RuntimeMoniker.Net462)]
- public class UnityResolution : ResolutionBenchmarks
+ public class UnityResolution_v4 : ResolutionBenchmarks
{
}
}
diff --git a/Adapters/V5/Create.cs b/Adapters/V5/Create.cs
new file mode 100644
index 0000000..24d4ad9
--- /dev/null
+++ b/Adapters/V5/Create.cs
@@ -0,0 +1,10 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Jobs;
+
+namespace Unity.v5
+{
+ [SimpleJob(RuntimeMoniker.Net472)]
+ public class Create : Benchmarks.Create
+ {
+ }
+}
diff --git a/Adapters/V5/UnityAdapterV5.cs b/Adapters/V5/UnityAdapterV5.cs
index 060c8ec..745b07b 100644
--- a/Adapters/V5/UnityAdapterV5.cs
+++ b/Adapters/V5/UnityAdapterV5.cs
@@ -1,12 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Unity.v5
+namespace Unity.v5
{
- public class UnityAdapterV5
+ // Marker type for Unity Adapter v5
+ public sealed class UnityAdapterV5
{
}
}
diff --git a/Adapters/V5/UnityContainerAPI.cs b/Adapters/V5/UnityContainerAPI.cs
deleted file mode 100644
index 92a6b94..0000000
--- a/Adapters/V5/UnityContainerAPI.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Unity.Benchmarks;
-
-namespace Unity.v5
-{
- [ShortRunJob(RuntimeMoniker.Net472)]
- public class UnityContainerAPI : ContainerAPI
- {
- }
-}
diff --git a/Adapters/V5/UnityRegisterAPI.cs b/Adapters/V5/UnityRegisterAPI.cs
deleted file mode 100644
index 9e50f30..0000000
--- a/Adapters/V5/UnityRegisterAPI.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Unity.Benchmarks;
-
-namespace Unity.v5
-{
- [ShortRunJob(RuntimeMoniker.Net472)]
- public class UnityRegisterAPI : RegisterAPI
- {
- }
-}
diff --git a/Adapters/V5/UnityResolution.cs b/Adapters/V5/UnityResolution.cs
index 1caebb9..f3e4bf8 100644
--- a/Adapters/V5/UnityResolution.cs
+++ b/Adapters/V5/UnityResolution.cs
@@ -5,7 +5,7 @@
namespace Unity.v5
{
[SimpleJob(RuntimeMoniker.Net472)]
- public class UnityResolution : ResolutionBenchmarks
+ public class UnityResolution_v5 : ResolutionBenchmarks
{
}
}
diff --git a/Adapters/V6/Create.cs b/Adapters/V6/Create.cs
new file mode 100644
index 0000000..363e16b
--- /dev/null
+++ b/Adapters/V6/Create.cs
@@ -0,0 +1,11 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Jobs;
+
+
+namespace Unity.V6
+{
+ [SimpleJob(RuntimeMoniker.NetCoreApp50)]
+ public class Create : Benchmarks.Create
+ {
+ }
+}
diff --git a/Adapters/V6/Unity.v6.csproj b/Adapters/V6/Unity.v6.csproj
index d52e8ab..aa23a29 100644
--- a/Adapters/V6/Unity.v6.csproj
+++ b/Adapters/V6/Unity.v6.csproj
@@ -4,11 +4,12 @@
Unity Container Regression Tests
Copyright © .NET Foundation and Contributors. All Rights Reserved
false
- net48;net50
+ net50
+
\ No newline at end of file
diff --git a/Adapters/V6/UnityAdapterV6.cs b/Adapters/V6/UnityAdapterV6.cs
index 501f894..141a1a2 100644
--- a/Adapters/V6/UnityAdapterV6.cs
+++ b/Adapters/V6/UnityAdapterV6.cs
@@ -1,12 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Unity.v6
+namespace Unity.v6
{
- public class UnityAdapterV6
+ // Marker type for Unity Adapter v6
+ public sealed class UnityAdapterV6
{
}
}
diff --git a/Adapters/V6/UnityContainerAPI.cs b/Adapters/V6/UnityContainerAPI.cs
deleted file mode 100644
index cd0f150..0000000
--- a/Adapters/V6/UnityContainerAPI.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Unity.Benchmarks;
-
-namespace Unity.v6
-{
- [ShortRunJob(RuntimeMoniker.Net48)]
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
- public class UnityContainerAPI : ContainerAPI
- {
- }
-}
diff --git a/Adapters/V6/UnityRegisterAPI.cs b/Adapters/V6/UnityRegisterAPI.cs
deleted file mode 100644
index f7110bd..0000000
--- a/Adapters/V6/UnityRegisterAPI.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Unity.Benchmarks;
-using Unity.Lifetime;
-using Unity.Resolution;
-
-namespace Unity.v6
-{
- [ShortRunJob(RuntimeMoniker.Net48)]
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
- public class UnityRegisterAPI : RegisterAPI
- {
- protected static ResolveDelegate ResolveDelegate = (ref IResolveContext c) => c.Type;
- protected RegistrationDescriptor[] registrations;
-
- public override void IterationSetup()
- {
- base.IterationSetup();
- registrations = new[]
- {
- new RegistrationDescriptor(typeof(object), null, (ITypeLifetimeManager)Manager1, typeof(object)),
- new RegistrationDescriptor(new object(), Name, (IInstanceLifetimeManager)Manager2, typeof(object)),
- new RegistrationDescriptor(ResolveDelegate, "string", (IFactoryLifetimeManager)Manager3, typeof(string))
- };
- }
-
- //[Benchmark(Description = "Register()", OperationsPerInvoke = 3)]
- //[BenchmarkCategory("register", "descriptors")]
- //public object Register()
- // => Container.Register(registrations);
- }
-}
diff --git a/Adapters/V6/UnityResolution.cs b/Adapters/V6/UnityResolution.cs
index 8c6f4b2..28e4250 100644
--- a/Adapters/V6/UnityResolution.cs
+++ b/Adapters/V6/UnityResolution.cs
@@ -6,7 +6,7 @@ namespace Unity.v6
{
[SimpleJob(RuntimeMoniker.Net48)]
[SimpleJob(RuntimeMoniker.NetCoreApp50)]
- public class UnityResolution : ResolutionBenchmarks
+ public class UnityResolution_v6 : ResolutionBenchmarks
{
}
}
diff --git a/Benchmarks/BenchmarkBase.cs b/Benchmarks/BenchmarkBase.cs
new file mode 100644
index 0000000..177e996
--- /dev/null
+++ b/Benchmarks/BenchmarkBase.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Benchmarks
+{
+ public class BenchmarkBase
+ {
+#if UNITY_V4
+ public const string VERSION = " v4";
+#elif UNITY_V5
+ public const string VERSION = " v5";
+#elif UNITY_V6
+ public const string VERSION = " v6";
+#else
+ public const string VERSION = "";
+#endif
+ }
+}
diff --git a/Benchmarks/Benchmarks.csproj b/Benchmarks/Benchmarks.csproj
index 60b5a63..a546847 100644
--- a/Benchmarks/Benchmarks.csproj
+++ b/Benchmarks/Benchmarks.csproj
@@ -1,33 +1,99 @@
-
- Unity Container Regression Tests
- Copyright © .NET Foundation and Contributors. All Rights Reserved
- true
- package.snk
- false
- ..\..\Container\src\Unity.Container.csproj
-
-
-
- net462;net472;net48;net50
- net50
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ net462
+
+
+
+
+ net472
+
+
+
+
+ net472
+
+
+
+
+ net50
+
+
+
+
+ STANDALONE;$(DefineConstants)
+ net462;net472;net50
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UNITY_V4;$(DefineConstants)
+ $(AssemblyName).V4
+
+
+
+
+
+
+
+
+
+ UNITY_V5;$(DefineConstants)
+ $(AssemblyName).V5
+
+
+
+
+
+
+
+
+ UNITY_V6;$(DefineConstants)
+ $(AssemblyName).V6
+
+
+
+
+
+
+
+
+
+ UNITY_V6;$(DefineConstants)
+ $(AssemblyName).V6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Unity Container Regression Tests
+ Copyright © .NET Foundation and Contributors. All Rights Reserved
+
\ No newline at end of file
diff --git a/Benchmarks/Container/ContainerAPI.cs b/Benchmarks/Container/ContainerAPI.cs
deleted file mode 100644
index ddb6b0e..0000000
--- a/Benchmarks/Container/ContainerAPI.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Engines;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Linq;
-using System;
-#if NET462
-using Microsoft.Practices.Unity;
-#else
-using Unity.Injection;
-using Unity.Lifetime;
-using Unity;
-#endif
-
-namespace Unity.Benchmarks
-{
- public class ContainerAPI
- {
- protected IUnityContainer Container;
- protected Consumer Consumer = new Consumer();
- protected static string Name = "name";
-
- protected static IInstanceLifetimeManager Manager = new ContainerControlledLifetimeManager();
- private static IEnumerable DefinedTypes = Assembly.GetAssembly(typeof(int)).DefinedTypes.Take(1000);
- protected static string[] TestNames = Enumerable.Repeat(null, 4)
- .Concat(DefinedTypes.Take(5).Select(t => t.Name))
- .Concat(DefinedTypes.Select(t => t.Name).Distinct().Take(100))
- .ToArray();
- protected static Type[] TestTypes = DefinedTypes.Where(t => t != typeof(IServiceProvider))
- .ToArray();
- static int size = 0;
- static int position = 0;
- protected static object Instance = new object();
- protected static RegistrationDescriptor[] RegistrationsData = TestNames.Select(name =>
- {
- var types = new Type[(++size & 0x7F)];
-
- Array.Copy(TestTypes, position, types, 0, types.Length);
- position = (position + types.Length) & 0x4FF;
-
- return new RegistrationDescriptor(Instance, name, Manager, types);
- }).ToArray();
-
-
- [GlobalSetup]
- public virtual void GlobalSetup()
- => Container = new UnityContainer().Register(RegistrationsData);
-
-
- [Benchmark(Description = "new UnityContainer()")]
- [BenchmarkCategory("new")]
- public object NewUnityContainer()
- => new UnityContainer();
-
-
- [Benchmark(Description = "CreateChildContainer()")]
- [BenchmarkCategory("new", "child")]
- public object NewChildContainer()
- => Container.CreateChildContainer();
-
-
- [Benchmark(Description = "Container.Registrations")]
- [BenchmarkCategory("registrations")]
- public object Registrations()
- => Container.Registrations;
-
-
- [Benchmark(Description = "Registrations.ToArray(6351)")]
- [BenchmarkCategory("registrations", "ToArray")]
- public void RegistrationsToArray()
- => Container.Registrations.Consume(Consumer);
-
- [Benchmark(Description = "Registrations.PerRegistration", OperationsPerInvoke = 6351)]
- [BenchmarkCategory("registrations", "ToArray")]
- public void RegistrationsPerRegistration()
- => Container.Registrations.Consume(Consumer);
-
-
- [Benchmark(Description = "Container.IsRegistered(true)")]
- [BenchmarkCategory("check", "true")]
- public virtual bool IsRegistered()
- => Container.IsRegistered(typeof(IUnityContainer), null);
-
-
- [Benchmark(Description = "Container.IsRegistered(false)")]
- [BenchmarkCategory("check", "false")]
- public virtual bool IsNotRegistered()
- => Container.IsRegistered(typeof(object), null);
- }
-}
diff --git a/Benchmarks/Container/Create.cs b/Benchmarks/Container/Create.cs
new file mode 100644
index 0000000..53ade24
--- /dev/null
+++ b/Benchmarks/Container/Create.cs
@@ -0,0 +1,33 @@
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+#if UNITY_V4
+using Microsoft.Practices.Unity;
+#else
+using Unity.Injection;
+using Unity.Lifetime;
+using Unity;
+#endif
+
+namespace Unity.Benchmarks
+{
+ public partial class Create
+ {
+ private static IUnityContainer Container;
+
+
+ [GlobalSetup]
+ public static void InitializeClass()
+ {
+ Container = new UnityContainer();
+ }
+
+
+ [Benchmark(Description = "new UnityContainer()" + BenchmarkBase.VERSION), BenchmarkCategory("new", "UnityContainer")]
+ public object New_UnityContainer() => new UnityContainer();
+
+
+
+ [Benchmark(Description = "CreateChildContainer()" + BenchmarkBase.VERSION), BenchmarkCategory("new", "ChildContainer")]
+ public object CreateChildContainer() => Container.CreateChildContainer();
+ }
+}
diff --git a/Benchmarks/Container/RegisterAPI.cs b/Benchmarks/Container/RegisterAPI.cs
deleted file mode 100644
index d1caf85..0000000
--- a/Benchmarks/Container/RegisterAPI.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using BenchmarkDotNet.Attributes;
-using System;
-using Unity.Resolution;
-#if NET462
-using Microsoft.Practices.Unity;
-#else
-using Unity.Injection;
-using Unity.Lifetime;
-using Unity;
-#endif
-
-namespace Unity.Benchmarks
-{
- public class RegisterAPI
- {
- protected static LifetimeManager Manager1;
- protected static LifetimeManager Manager2;
- protected static LifetimeManager Manager3;
- protected static IUnityContainer Container;
- protected static Func Factory = (c, t, n) => c;
- protected const string Name = "name";
- protected object Instance1 = new object();
- protected object Instance2 = new object();
- protected object Instance3 = "object";
-#if NET462
- protected InjectionFactory InjectionFactory = new InjectionFactory(Factory);
-#endif
-
-
- //[IterationSetup]
- public virtual void IterationSetup()
- {
- Container = new UnityContainer();
- Manager1 = new ContainerControlledLifetimeManager();
- Manager2 = new ContainerControlledLifetimeManager();
- Manager3 = new ContainerControlledLifetimeManager();
- }
-
- [Benchmark(Description = "RegisterType()", OperationsPerInvoke = 3)]
- [BenchmarkCategory("register", "type")]
- public virtual object RegisterType()
- {
-#if NET462
- Container.RegisterType(typeof(object), Manager1);
- Container.RegisterType(typeof(object), Name, Manager2);
- Container.RegisterType(typeof(string), "string", Manager3);
-#else
- Container.RegisterType(typeof(object), (ITypeLifetimeManager)Manager1);
- Container.RegisterType(typeof(object), Name, (ITypeLifetimeManager)Manager2);
- Container.RegisterType(typeof(string), "string", (ITypeLifetimeManager)Manager3);
-#endif
-
- return Container;
- }
-
- [Benchmark(Description = "RegisterInstance()", OperationsPerInvoke = 3)]
- [BenchmarkCategory("register", "instance")]
- public virtual object RegisterInstance()
- {
-#if NET462
- Container.RegisterInstance(typeof(object), Instance1, Manager1);
- Container.RegisterInstance(typeof(object), Name, Instance2, Manager2);
- Container.RegisterInstance(typeof(string), "string", Instance3, Manager3);
-#else
- Container.RegisterInstance(typeof(object), Instance1, (IInstanceLifetimeManager)Manager1);
- Container.RegisterInstance(typeof(object), Name, Instance2, (IInstanceLifetimeManager)Manager2);
- Container.RegisterInstance(typeof(string), "string", Instance3, (IInstanceLifetimeManager)Manager3);
-#endif
-
- return Container;
- }
-
- [Benchmark(Description = "RegisterFactory()", OperationsPerInvoke = 3)]
- [BenchmarkCategory("register", "factory")]
- public virtual object RegisterFactory()
- {
-#if NET462
- Container.RegisterType(typeof(object), Manager1, InjectionFactory);
- Container.RegisterType(typeof(object), Name, Manager2, InjectionFactory);
- Container.RegisterType(typeof(string), "string", Manager3, InjectionFactory);
-#else
- Container.RegisterFactory(typeof(object), Factory, (IFactoryLifetimeManager)Manager1);
- Container.RegisterFactory(typeof(object), Name, Factory, (IFactoryLifetimeManager)Manager2);
- Container.RegisterFactory(typeof(string), "string", Factory, (IFactoryLifetimeManager)Manager3);
-
-#endif
- return Container;
- }
- }
-}
diff --git a/Benchmarks/Environment.cs b/Benchmarks/Environment.cs
new file mode 100644
index 0000000..70e873f
--- /dev/null
+++ b/Benchmarks/Environment.cs
@@ -0,0 +1,55 @@
+// Version
+
+#if UNITY_V4
+// Unity v4.0.1
+#endif
+
+#if UNITY_V5
+// Unity v5.11.x
+#endif
+
+#if UNITY_V6
+// Unity v6.x
+#endif
+
+
+// Behavior
+
+#if BEHAVIOR_V4
+// Unity v4.0.1
+#endif
+
+#if BEHAVIOR_V5
+// Unity v5.11.x
+#endif
+
+#if BEHAVIOR_V6
+// v6.x
+#endif
+
+// .NET Framework
+
+#if NET5_0
+// Current Framework NET5.0
+#endif
+#if NET48
+// Current Framework NET4.8
+#endif
+#if NET47
+// Current Framework NET4.7
+#endif
+#if NET471
+// Current Framework NET4.7.1
+#endif
+#if NET46
+// Current Framework NET4.6
+#endif
+#if NET461
+// Current Framework NET4.6.1
+#endif
+#if NET462
+// Current Framework NET4.6.2
+#endif
+#if NET45
+// Current Framework NET4.5
+#endif
diff --git a/Benchmarks/Pipeline/Create.cs b/Benchmarks/Pipeline/Create.cs
new file mode 100644
index 0000000..9e45d30
--- /dev/null
+++ b/Benchmarks/Pipeline/Create.cs
@@ -0,0 +1,22 @@
+using BenchmarkDotNet.Attributes;
+using Benchmarks;
+#if UNITY_V4
+using Microsoft.Practices.Unity;
+#else
+using Unity.Injection;
+using Unity.Lifetime;
+using Unity;
+#endif
+
+namespace Unity.Benchmarks
+{
+ public partial class PipelineBenchmarks
+ {
+ [Benchmark(Description = "Create Pipeline for Unknown" + BenchmarkBase.VERSION), BenchmarkCategory("Pipeline", "Create")]
+ public object Pipeline_Create_Unknown() => Container.Resolve(typeof(object));
+
+
+ [Benchmark(Description = "Create Pipeline for Registered" + BenchmarkBase.VERSION), BenchmarkCategory("Pipeline", "Create")]
+ public object Pipeline_Create_Registered() => Container.Resolve(typeof(Service));
+ }
+}
diff --git a/Benchmarks/Pipeline/Pipeline.FromRegistered.cs b/Benchmarks/Pipeline/Pipeline.FromRegistered.cs
deleted file mode 100644
index 3570363..0000000
--- a/Benchmarks/Pipeline/Pipeline.FromRegistered.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using BenchmarkDotNet.Attributes;
-using System;
-#if NET462
-using Microsoft.Practices.Unity;
-#else
-using Unity.Injection;
-using Unity.Lifetime;
-using Unity;
-#endif
-
-namespace Unity.Benchmarks
-{
- public partial class PipelineBenchmarks
- {
- [Benchmark]
- public object FromRegistered_Complete_Transient()
- => Container.Resolve(typeof(Service), EveryTime);
-
- [Benchmark]
- public object FromRegistered_Complete_Balanced_()
- => Container.Resolve(typeof(Service), OnceInAWhile);
-
- [Benchmark]
- public object FromRegistered_Complete_Singleton()
- => Container.Resolve(typeof(Service), OnceInLifetime);
- }
-}
diff --git a/Benchmarks/Pipeline/Pipeline.Setup.cs b/Benchmarks/Pipeline/Pipeline.Setup.cs
deleted file mode 100644
index 76f7296..0000000
--- a/Benchmarks/Pipeline/Pipeline.Setup.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-using BenchmarkDotNet.Attributes;
-using System;
-using System.Collections.Generic;
-using Unity.Resolution;
-using Unity.Container;
-using System.Reflection;
-#if NET462
-using Microsoft.Practices.Unity;
-#else
-using Unity.Injection;
-using Unity.Lifetime;
-using Unity;
-#endif
-
-namespace Unity.Benchmarks
-{
- public partial class PipelineBenchmarks
- {
- const string EveryTime = "EveryTime";
- const string OnceInLifetime = "OnceInLifetime";
- const string OnceInAWhile = "OnceInAWhile";
-
-#if NET462 || NET472
- protected IUnityContainer Container;
-#else
- protected IUnityContainer Container;
- protected IUnityContainerAsync ContainerAsync;
- protected IServiceProvider ServiceProvider;
-#endif
-
- [GlobalSetup]
- public virtual void GlobalSetup()
- {
- Container = new UnityContainer()
- .RegisterType(typeof(Service), EveryTime, new EveryTimeManager())
- .RegisterType(typeof(Service), OnceInLifetime, new OnceInLifetimeManager())
- .RegisterType(typeof(Service), OnceInAWhile, new OnceInAWhileManager());
-#if !NET462 && !NET472
- ContainerAsync = (IUnityContainerAsync)Container;
- ServiceProvider = (IServiceProvider)Container;
-#endif
- }
-
-
- public interface IService { }
-
- public class Service : IService { }
-
- public class OtherService : IService { }
-
- public class CompleteService : IService { }
-
-
- public class EveryTimeManager : LifetimeManager, ITypeLifetimeManager
- {
- public override ResolutionStyle Style => ResolutionStyle.EveryTime;
-
- protected override LifetimeManager OnCreateLifetimeManager() => throw new NotSupportedException();
-
- public override void SetValue(object newValue, ICollection scope) { }
-
- public override object TryGetValue(ICollection scope)
- {
- Pipeline = null;
- return UnityContainer.NoValue;
- }
- public override object GetValue(ICollection scope)
- {
- Pipeline = null;
- return UnityContainer.NoValue;
- }
- }
-
- public class OnceInLifetimeManager : LifetimeManager, ITypeLifetimeManager
- {
- public override ResolutionStyle Style => ResolutionStyle.OnceInLifetime;
-
- protected override LifetimeManager OnCreateLifetimeManager() => throw new NotSupportedException();
-
- public override void SetValue(object newValue, ICollection lifetime)
- { }
- public override object TryGetValue(ICollection lifetime)
- {
- Pipeline = null;
- return UnityContainer.NoValue;
- }
- public override object GetValue(ICollection lifetime)
- {
- Pipeline = null;
- return UnityContainer.NoValue;
- }
- }
-
- public class OnceInAWhileManager : LifetimeManager, ITypeLifetimeManager
- {
- public override ResolutionStyle Style => ResolutionStyle.OnceInWhile;
-
- protected override LifetimeManager OnCreateLifetimeManager() => throw new NotSupportedException();
-
- public override void SetValue(object newValue, ICollection lifetime)
- { }
- public override object TryGetValue(ICollection lifetime)
- {
- Pipeline = null;
- return UnityContainer.NoValue;
- }
- public override object GetValue(ICollection lifetime)
- {
- Pipeline = null;
- return UnityContainer.NoValue;
- }
- }
- }
-}
diff --git a/Benchmarks/Pipeline/Setup.V4.cs b/Benchmarks/Pipeline/Setup.V4.cs
new file mode 100644
index 0000000..8c6548f
--- /dev/null
+++ b/Benchmarks/Pipeline/Setup.V4.cs
@@ -0,0 +1,66 @@
+using System.Linq;
+using Microsoft.Practices.Unity.ObjectBuilder;
+using Microsoft.Practices.ObjectBuilder2;
+using Microsoft.Practices.Unity;
+
+namespace Unity.Benchmarks
+{
+ ///
+ /// An extension to install custom strategy that disables
+ /// saving of created build plan
+ ///
+ public class PipelineSpyExtension : UnityContainerExtension
+ {
+ protected override void Initialize()
+ {
+ // Unity v4 did not offer any way of replacing built in strategies
+ // The only way to do it is to clear and repopulate
+
+ // Get an array of all strategies.
+ var strategies = Context.Strategies.MakeStrategyChain()
+ .ToArray();
+ // Clear the chain
+ Context.Strategies.Clear();
+
+ // Repopulate main strategy chain, replacing the last one
+ // Main strategy chain
+ Context.Strategies.Add(strategies[0], UnityBuildStage.TypeMapping);
+ Context.Strategies.Add(strategies[1], UnityBuildStage.Lifetime);
+ Context.Strategies.Add(strategies[2], UnityBuildStage.Lifetime);
+ Context.Strategies.Add(strategies[3], UnityBuildStage.Creation);
+
+ Context.Strategies.Add(new PipelineSpyStrategy(), UnityBuildStage.Creation);
+ }
+ }
+
+ ///
+ /// Unity v5 uses to create and save
+ /// a build plan for each created type
+ ///
+ public class PipelineSpyStrategy : BuildPlanStrategy
+ {
+ // Override default implementation
+ public override void PreBuildUp(IBuilderContext context)
+ {
+ IPolicyList buildPlanLocation;
+
+ var plan = context.Policies.Get(context.BuildKey, out buildPlanLocation);
+ if (plan == null)
+ {
+ IPolicyList creatorLocation;
+
+ var planCreator = context.Policies.Get(context.BuildKey, out creatorLocation);
+ if (planCreator != null)
+ {
+ plan = planCreator.CreatePlan(context, context.BuildKey);
+ // Disable pipeline save so it builds it every time
+ //(buildPlanLocation ?? creatorLocation).Set(plan, context.BuildKey);
+ }
+ }
+ if (plan != null)
+ {
+ plan.BuildUp(context);
+ }
+ }
+ }
+}
diff --git a/Benchmarks/Pipeline/Setup.V5.cs b/Benchmarks/Pipeline/Setup.V5.cs
new file mode 100644
index 0000000..b431ce7
--- /dev/null
+++ b/Benchmarks/Pipeline/Setup.V5.cs
@@ -0,0 +1,79 @@
+using System;
+using Unity.Strategies;
+using Unity.Extension;
+using Unity.Policy;
+using Unity.Builder;
+using Unity.Resolution;
+using Unity.Registration;
+using System.Globalization;
+
+namespace Unity.Benchmarks
+{
+ ///
+ /// An extension to install custom strategy that disables
+ /// saving of created build plan
+ ///
+ public class PipelineSpyExtension : UnityContainerExtension
+ {
+ protected override void Initialize()
+ {
+ Context.Strategies.Add(new PipelineSpyStrategy(), UnityBuildStage.PreCreation);
+ }
+ }
+
+ ///
+ /// Unity v5 uses to create and save
+ /// a build plan for each created type
+ ///
+ public class PipelineSpyStrategy : BuildPlanStrategy
+ {
+ // Override default implementation
+ public override void PreBuildUp(ref BuilderContext context)
+ {
+ var resolver = context.Registration.Get>() ?? (ResolveDelegate)
+ GetGeneric(ref context, typeof(ResolveDelegate));
+
+ if (null == resolver)
+ {
+#if NETCOREAPP1_0 || NETSTANDARD1_0
+ if (!(context.Registration is ContainerRegistration) && context.RegistrationType.GetTypeInfo().IsGenericTypeDefinition)
+#else
+ if (!(context.Registration is ContainerRegistration) && context.RegistrationType.IsGenericTypeDefinition)
+#endif
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
+ "The type {0} is an open generic type. An open generic type cannot be resolved.",
+ context.RegistrationType.FullName), new Exception());
+ }
+ else if (context.Type.IsArray && context.Type.GetArrayRank() > 1)
+ {
+ var message = $"Invalid array {context.Type}. Only arrays of rank 1 are supported";
+ throw new ArgumentException(message, new Exception());
+ }
+
+ var factory = context.Registration.Get() ?? (ResolveDelegateFactory)(
+ context.Get(context.Type, UnityContainer.All, typeof(ResolveDelegateFactory)) ??
+ GetGeneric(ref context, typeof(ResolveDelegateFactory)) ??
+ context.Get(null, null, typeof(ResolveDelegateFactory)));
+
+ if (null != factory)
+ {
+ resolver = factory(ref context);
+
+ // Disable saving, force creation every time
+ // context.Registration.Set(typeof(ResolveDelegate), resolver);
+ context.Existing = resolver(ref context);
+ }
+ else
+ throw new ResolutionFailedException(context.Type, context.Name, $"Failed to find Resolve Delegate Factory for Type {context.Type}");
+ }
+ else
+ {
+ context.Existing = resolver(ref context);
+ }
+
+ // Prevent further processing
+ context.BuildComplete = true;
+ }
+ }
+}
diff --git a/Benchmarks/Pipeline/Setup.V6.cs b/Benchmarks/Pipeline/Setup.V6.cs
new file mode 100644
index 0000000..df8f1bb
--- /dev/null
+++ b/Benchmarks/Pipeline/Setup.V6.cs
@@ -0,0 +1,17 @@
+using System;
+using Unity.Extension;
+
+namespace Unity.Benchmarks
+{
+ ///
+ /// An extension to install custom strategy that disables
+ /// saving of created build plan
+ ///
+ public class PipelineSpyExtension : UnityContainerExtension
+ {
+ protected override void Initialize()
+ {
+ //Context.Strategies.Add(new PipelineSpyStrategy(), UnityBuildStage.PreCreation);
+ }
+ }
+}
diff --git a/Benchmarks/Pipeline/Setup.cs b/Benchmarks/Pipeline/Setup.cs
new file mode 100644
index 0000000..8fc41b8
--- /dev/null
+++ b/Benchmarks/Pipeline/Setup.cs
@@ -0,0 +1,34 @@
+using BenchmarkDotNet.Attributes;
+#if UNITY_V4
+using Microsoft.Practices.Unity;
+#else
+using Unity.Injection;
+using Unity.Lifetime;
+using Unity;
+#endif
+
+namespace Unity.Benchmarks
+{
+ public partial class PipelineBenchmarks
+ {
+ private static IUnityContainer Container;
+
+ [GlobalSetup]
+ public static void InitializeClass()
+ {
+ Container = new UnityContainer()
+ .AddExtension(new PipelineSpyExtension())
+ .RegisterType();
+ }
+ }
+
+
+ #region Test Data
+
+ public class Service
+ {
+
+ }
+
+ #endregion
+}
diff --git a/Benchmarks/Resolution/Resolve.Setup.cs b/Benchmarks/Resolution/Resolve.Setup.cs
index 9489f6e..646e6aa 100644
--- a/Benchmarks/Resolution/Resolve.Setup.cs
+++ b/Benchmarks/Resolution/Resolve.Setup.cs
@@ -1,5 +1,6 @@
using BenchmarkDotNet.Attributes;
using System;
+using BenchmarkDotNet.Jobs;
#if NET462
using Microsoft.Practices.Unity;
#else
@@ -10,6 +11,10 @@
namespace Unity.Benchmarks
{
+ [ShortRunJob(RuntimeMoniker.Net462)]
+ [SimpleJob(RuntimeMoniker.Net472)]
+ [ShortRunJob(RuntimeMoniker.Net48)]
+ [SimpleJob(RuntimeMoniker.NetCoreApp50)]
public partial class ResolutionBenchmarks
{
#if NET462 || NET472
diff --git a/Benchmarks/package.snk b/Benchmarks/package.snk
deleted file mode 100644
index 986f91e..0000000
Binary files a/Benchmarks/package.snk and /dev/null differ
diff --git a/Benchmarks Tests.sln b/Container Benchmarks.sln
similarity index 54%
rename from Benchmarks Tests.sln
rename to Container Benchmarks.sln
index b319e25..ccd9c49 100644
--- a/Benchmarks Tests.sln
+++ b/Container Benchmarks.sln
@@ -7,13 +7,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Runner", "Runner\Runner.csp
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{023E0805-E13F-48F6-B0AC-776E7DAC8E18}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Adapters", "Adapters", "{5B7A2174-A6E6-4B28-9C42-569275D7B3DF}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks.Tests", "Tests\Benchmarks.Tests.csproj", "{1D633525-3B20-4D77-81AF-F5311E054C06}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.v4", "Adapters\V4\Unity.v4.csproj", "{52CA989F-F741-4E77-A82F-9930C97B7161}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.v4", "Adapters\V4\Unity.v4.csproj", "{82430F08-BA18-4B17-8DBD-EC4BF252B9E8}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.v5", "Adapters\V5\Unity.v5.csproj", "{3E921D4E-E8EE-4AB1-B2E9-03D36E4FCFFB}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Adapters", "Adapters", "{F2EBE6DD-CCF5-4261-8ADD-0C9083182126}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.v6", "Adapters\V6\Unity.v6.csproj", "{9D376979-A9B6-497E-965C-397E59442A12}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.v5", "Adapters\V5\Unity.v5.csproj", "{DA97DF63-35B3-48D7-BBBA-C0FF6549DF3F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.v6", "Adapters\V6\Unity.v6.csproj", "{D6DB1CC8-73C5-4C59-9CDC-93B420810762}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -25,30 +27,34 @@ Global
{925F5BA8-FC9D-45BC-8013-AF95C67ED742}.Debug|Any CPU.Build.0 = Debug|Any CPU
{925F5BA8-FC9D-45BC-8013-AF95C67ED742}.Release|Any CPU.ActiveCfg = Release|Any CPU
{925F5BA8-FC9D-45BC-8013-AF95C67ED742}.Release|Any CPU.Build.0 = Release|Any CPU
- {023E0805-E13F-48F6-B0AC-776E7DAC8E18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {023E0805-E13F-48F6-B0AC-776E7DAC8E18}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {023E0805-E13F-48F6-B0AC-776E7DAC8E18}.Debug|Any CPU.ActiveCfg = Release|Any CPU
+ {023E0805-E13F-48F6-B0AC-776E7DAC8E18}.Debug|Any CPU.Build.0 = Release|Any CPU
{023E0805-E13F-48F6-B0AC-776E7DAC8E18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{023E0805-E13F-48F6-B0AC-776E7DAC8E18}.Release|Any CPU.Build.0 = Release|Any CPU
- {52CA989F-F741-4E77-A82F-9930C97B7161}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {52CA989F-F741-4E77-A82F-9930C97B7161}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {52CA989F-F741-4E77-A82F-9930C97B7161}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {52CA989F-F741-4E77-A82F-9930C97B7161}.Release|Any CPU.Build.0 = Release|Any CPU
- {3E921D4E-E8EE-4AB1-B2E9-03D36E4FCFFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3E921D4E-E8EE-4AB1-B2E9-03D36E4FCFFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3E921D4E-E8EE-4AB1-B2E9-03D36E4FCFFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3E921D4E-E8EE-4AB1-B2E9-03D36E4FCFFB}.Release|Any CPU.Build.0 = Release|Any CPU
- {9D376979-A9B6-497E-965C-397E59442A12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9D376979-A9B6-497E-965C-397E59442A12}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9D376979-A9B6-497E-965C-397E59442A12}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9D376979-A9B6-497E-965C-397E59442A12}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1D633525-3B20-4D77-81AF-F5311E054C06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1D633525-3B20-4D77-81AF-F5311E054C06}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1D633525-3B20-4D77-81AF-F5311E054C06}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1D633525-3B20-4D77-81AF-F5311E054C06}.Release|Any CPU.Build.0 = Release|Any CPU
+ {82430F08-BA18-4B17-8DBD-EC4BF252B9E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {82430F08-BA18-4B17-8DBD-EC4BF252B9E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {82430F08-BA18-4B17-8DBD-EC4BF252B9E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {82430F08-BA18-4B17-8DBD-EC4BF252B9E8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DA97DF63-35B3-48D7-BBBA-C0FF6549DF3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DA97DF63-35B3-48D7-BBBA-C0FF6549DF3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DA97DF63-35B3-48D7-BBBA-C0FF6549DF3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DA97DF63-35B3-48D7-BBBA-C0FF6549DF3F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D6DB1CC8-73C5-4C59-9CDC-93B420810762}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D6DB1CC8-73C5-4C59-9CDC-93B420810762}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D6DB1CC8-73C5-4C59-9CDC-93B420810762}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D6DB1CC8-73C5-4C59-9CDC-93B420810762}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {52CA989F-F741-4E77-A82F-9930C97B7161} = {5B7A2174-A6E6-4B28-9C42-569275D7B3DF}
- {3E921D4E-E8EE-4AB1-B2E9-03D36E4FCFFB} = {5B7A2174-A6E6-4B28-9C42-569275D7B3DF}
- {9D376979-A9B6-497E-965C-397E59442A12} = {5B7A2174-A6E6-4B28-9C42-569275D7B3DF}
+ {82430F08-BA18-4B17-8DBD-EC4BF252B9E8} = {F2EBE6DD-CCF5-4261-8ADD-0C9083182126}
+ {DA97DF63-35B3-48D7-BBBA-C0FF6549DF3F} = {F2EBE6DD-CCF5-4261-8ADD-0C9083182126}
+ {D6DB1CC8-73C5-4C59-9CDC-93B420810762} = {F2EBE6DD-CCF5-4261-8ADD-0C9083182126}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {032A4232-BBBB-431E-A478-D3EAA6CA330C}
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000..a6550ce
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,50 @@
+
+
+
+
+ ..\..\Container\src\Unity.Container.csproj
+ ..\..\unity\source\Unity\Src\Unity.csproj
+ 9.0
+
+
+
+
+
+
+
+ LEGACY
+
+
+
+
+
+
+ MASTER
+
+
+
+
+
+
+ DEVELOP
+
+
+
+
+
+
+
+ LATEST
+
+
+
+
+
+
+ STANDALONE
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NuGet.Config b/NuGet.Config
new file mode 100644
index 0000000..dadc1a2
--- /dev/null
+++ b/NuGet.Config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Runner/Environment.cs b/Runner/Environment.cs
new file mode 100644
index 0000000..fe00293
--- /dev/null
+++ b/Runner/Environment.cs
@@ -0,0 +1,58 @@
+// Version
+
+#if UNITY_V4
+// Unity v4.0.1
+#endif
+
+#if UNITY_V5
+// Unity v5.11.x
+#endif
+
+#if UNITY_V6
+// Unity v6.x
+#endif
+
+
+// Behavior
+
+#if BEHAVIOR_V4
+// Unity v4.0.1
+#endif
+
+#if BEHAVIOR_V5
+// Unity v5.11.x
+#endif
+
+#if BEHAVIOR_V6
+// v6.x
+#endif
+
+// .NET Framework
+
+#if NET5_0
+// Current Framework NET5.0
+#endif
+#if NET48
+// Current Framework NET4.8
+#endif
+#if NET47
+// Current Framework NET4.7
+#endif
+#if NET471
+// Current Framework NET4.7.1
+#endif
+#if NET472
+// Current Framework NET4.7.2
+#endif
+#if NET46
+// Current Framework NET4.6
+#endif
+#if NET461
+// Current Framework NET4.6.1
+#endif
+#if NET462
+// Current Framework NET4.6.2
+#endif
+#if NET45
+// Current Framework NET4.5
+#endif
diff --git a/Runner/Program.cs b/Runner/Program.cs
index 47cf60d..f0a7274 100644
--- a/Runner/Program.cs
+++ b/Runner/Program.cs
@@ -1,7 +1,11 @@
using BenchmarkDotNet.Running;
+#if STANDALONE
using Unity.v4;
using Unity.v5;
using Unity.v6;
+#else
+using Benchmarks;
+#endif
namespace Unity.Benchmark
{
@@ -9,11 +13,15 @@ class Program
{
static void Main(string[] args)
{
- BenchmarkSwitcher.FromAssemblies(new[]
+ BenchmarkSwitcher.FromAssemblies(new[]
{
+#if STANDALONE
typeof(UnityAdapterV4).Assembly,
typeof(UnityAdapterV5).Assembly,
typeof(UnityAdapterV6).Assembly,
+#else
+ typeof(BenchmarkBase).Assembly
+#endif
}).Run(args);
}
}
diff --git a/Runner/Runner.csproj b/Runner/Runner.csproj
index 0c866da..d198518 100644
--- a/Runner/Runner.csproj
+++ b/Runner/Runner.csproj
@@ -1,26 +1,66 @@
-
- Exe
- net5.0
- NU1702
-
+
+ Exe
+ NU1702
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+ net462
+
+
+
+
+
+
+
+ net472
+
+
+
+
+
+
+
+ net472
+
+
+
+
+
+
+
+ net50
+
+
+
+
+
+
+
+ net50
+ STANDALONE;$(DefineConstants)
+
+
+
+
+
+
+
+
diff --git a/Tests/BenchmarkTestBase.cs b/Tests/BenchmarkTestBase.cs
new file mode 100644
index 0000000..6133c22
--- /dev/null
+++ b/Tests/BenchmarkTestBase.cs
@@ -0,0 +1,56 @@
+using BenchmarkDotNet.Attributes;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Linq;
+
+namespace Benchmark.Tests
+{
+ [TestClass]
+ public class BenchmarkTestBase
+ where TBenchmark : class, new()
+ {
+ #region Fields
+
+ private static Action IterationSetupAction;
+ private static Action IterationCleanupAction;
+ protected static TBenchmark Benchmark = new TBenchmark();
+
+ #endregion
+
+
+ #region Constructors
+
+ static BenchmarkTestBase()
+ {
+ var methods = typeof(TBenchmark).GetMethods();
+ var globalSetup = methods.Where(info => info.IsDefined(typeof(GlobalSetupAttribute), true))
+ .FirstOrDefault();
+ globalSetup?.Invoke(null, Array.Empty