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()); + + var method = methods.Where(info => info.IsDefined(typeof(IterationSetupAttribute), true)) + .FirstOrDefault(); + + if (method is not null) + IterationSetupAction = (Action)method.CreateDelegate(typeof(Action), Benchmark); + + method = methods.Where(info => info.IsDefined(typeof(IterationCleanupAttribute), true)) + .FirstOrDefault(); + + if (method is not null) + IterationCleanupAction = (Action)method.CreateDelegate(typeof(Action), Benchmark); + } + + #endregion + + + #region Scaffolding + + [TestInitialize] + public virtual void IterationSetup() => IterationSetupAction?.Invoke(); + + [TestCleanup] + public virtual void IterationCleanup() => IterationCleanupAction?.Invoke(); + + #endregion + } +} diff --git a/Tests/Benchmarks.Tests.csproj b/Tests/Benchmarks.Tests.csproj new file mode 100644 index 0000000..6134808 --- /dev/null +++ b/Tests/Benchmarks.Tests.csproj @@ -0,0 +1,58 @@ + + + + + + net462 + + + + + net472 + + + + + net472 + + + + + net50 + + + + + STANDALONE;$(DefineConstants) + net462;net472;net50 + + + + + + + + + UNITY_V6;$(DefineConstants) + UNITY_V6;$(DefineConstants) + UNITY_V5;$(DefineConstants) + UNITY_V4;$(DefineConstants) + UNITY_V4;$(DefineConstants) + + + + + + + + + + + + + + Unity Container Regression Tests + Copyright © .NET Foundation and Contributors. All Rights Reserved + + + \ No newline at end of file diff --git a/Tests/Container/TestCreate.cs b/Tests/Container/TestCreate.cs new file mode 100644 index 0000000..890d3ac --- /dev/null +++ b/Tests/Container/TestCreate.cs @@ -0,0 +1,18 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Benchmark.Tests; +using Unity.Benchmarks; + +namespace Continer +{ + [TestClass] + public partial class TestCreate : BenchmarkTestBase + { + [TestMethod] + public void New_UnityContainer() + => Assert.IsNotNull(Benchmark.New_UnityContainer()); + + [TestMethod] + public void CreateChildContainer() + => Assert.IsNotNull(Benchmark.CreateChildContainer()); + } +} diff --git a/Tests/Pipeline/Create.cs b/Tests/Pipeline/Create.cs new file mode 100644 index 0000000..51bf433 --- /dev/null +++ b/Tests/Pipeline/Create.cs @@ -0,0 +1,17 @@ +using BenchmarkDotNet.Attributes; +using Benchmarks; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Pipeline +{ + public partial class TestPipelineBenchmarks + { + [TestMethod] + public void Pipeline_Create_Unknown() + => Assert.IsNotNull(Benchmark.Pipeline_Create_Unknown()); + + [TestMethod] + public void Pipeline_Create_Registered() + => Assert.IsNotNull(Benchmark.Pipeline_Create_Registered()); + } +} diff --git a/Tests/Pipeline/Setup.cs b/Tests/Pipeline/Setup.cs new file mode 100644 index 0000000..808c9ad --- /dev/null +++ b/Tests/Pipeline/Setup.cs @@ -0,0 +1,11 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Benchmark.Tests; +using Unity.Benchmarks; + +namespace Pipeline +{ + [TestClass] + public partial class TestPipelineBenchmarks : BenchmarkTestBase + { + } +}