Skip to content

Commit b96c279

Browse files
committed
Minor performance optimizations
1 parent 741176e commit b96c279

File tree

4 files changed

+70
-13
lines changed

4 files changed

+70
-13
lines changed

src/Storage/StagedStrategyChain.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@ public class StagedStrategyChain<TStrategyType, TStageEnum> : IStagedStrategyCha
1919
{
2020
#region Fields
2121

22+
private static readonly int _size = typeof(TStageEnum).GetTypeInfo().DeclaredFields.Count(f => f.IsPublic && f.IsStatic);
2223
private readonly object _lockObject = new object();
2324
private readonly StagedStrategyChain<TStrategyType, TStageEnum> _innerChain;
24-
private readonly IList<TStrategyType>[] _stages = new IList<TStrategyType>[typeof(TStageEnum).GetTypeInfo()
25-
.DeclaredFields
26-
.Count(f => f.IsPublic && f.IsStatic)];
25+
private readonly IList<TStrategyType>[] _stages = new IList<TStrategyType>[_size];
2726

2827
private IEnumerable<TStrategyType> _cache;
2928

src/UnityContainer.ContainerContext.cs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ private class ContainerContext : ExtensionContext,
2727
{
2828
#region Fields
2929

30+
private readonly object syncRoot = new object();
3031
private readonly UnityContainer _container;
3132

3233
#endregion
@@ -47,9 +48,52 @@ public ContainerContext(UnityContainer container)
4748

4849
public override IUnityContainer Container => _container;
4950

50-
public override IStagedStrategyChain<IBuilderStrategy, UnityBuildStage> Strategies => _container._strategies;
51+
public override IStagedStrategyChain<IBuilderStrategy, UnityBuildStage> Strategies
52+
{
53+
get
54+
{
55+
if (null != _container._parent &&
56+
_container._parent._strategies == _container._strategies)
57+
{
58+
lock (syncRoot)
59+
{
60+
if (_container._parent._strategies == _container._strategies)
61+
{
62+
_container._strategies.Invalidated -= _container.OnStrategiesChanged;
63+
_container._strategies =
64+
new StagedStrategyChain<IBuilderStrategy, UnityBuildStage>(_container._parent._strategies);
65+
_container._strategies.Invalidated += _container.OnStrategiesChanged;
66+
_container._lifetimeContainer.Add(_container._strategies);
67+
68+
}
69+
}
70+
}
71+
72+
return _container._strategies;
73+
}
74+
}
5175

52-
public override IStagedStrategyChain<IBuilderStrategy, BuilderStage> BuildPlanStrategies => _container._buildPlanStrategies;
76+
public override IStagedStrategyChain<IBuilderStrategy, BuilderStage> BuildPlanStrategies
77+
{
78+
get
79+
{
80+
if (null != _container._parent &&
81+
_container._parent._buildPlanStrategies == _container._buildPlanStrategies)
82+
{
83+
lock (syncRoot)
84+
{
85+
if (_container._parent._buildPlanStrategies == _container._buildPlanStrategies)
86+
{
87+
_container._buildPlanStrategies =
88+
new StagedStrategyChain<IBuilderStrategy, BuilderStage>(_container._parent._buildPlanStrategies);
89+
_container._lifetimeContainer.Add(_container._buildPlanStrategies);
90+
}
91+
}
92+
}
93+
94+
return _container._buildPlanStrategies;
95+
}
96+
}
5397

5498
public override IPolicyList Policies { get; }
5599

src/UnityContainer.Implementation.cs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ public partial class UnityContainer
3939
private readonly ContainerContext _context;
4040

4141
// Strategies
42-
private readonly StagedStrategyChain<IBuilderStrategy, UnityBuildStage> _strategies;
43-
private readonly StagedStrategyChain<IBuilderStrategy, BuilderStage> _buildPlanStrategies;
42+
private StagedStrategyChain<IBuilderStrategy, UnityBuildStage> _strategies;
43+
private StagedStrategyChain<IBuilderStrategy, BuilderStage> _buildPlanStrategies;
4444

4545
// Events
4646
private event EventHandler<RegisterEventArgs> Registering;
@@ -68,11 +68,13 @@ private UnityContainer(UnityContainer parent)
6868
_parent?._lifetimeContainer.Add(this);
6969

7070
// Strategies
71-
_strategies = new StagedStrategyChain<IBuilderStrategy, UnityBuildStage>(_parent?._strategies);
72-
_buildPlanStrategies = new StagedStrategyChain<IBuilderStrategy, BuilderStage>(_parent?._buildPlanStrategies);
71+
_strategies = _parent?._strategies;
72+
_buildPlanStrategies = _parent?._buildPlanStrategies;
73+
_registerTypeStrategies = _parent?._registerTypeStrategies;
74+
_strategyChain = _parent?._strategyChain;
7375

7476
// Lifetime
75-
_lifetimeContainer = new LifetimeContainer(this) { _strategies, _buildPlanStrategies };
77+
_lifetimeContainer = new LifetimeContainer(this);
7678

7779
// Default Policies
7880
if (null == _parent) InitializeRootContainer();
@@ -84,7 +86,6 @@ private UnityContainer(UnityContainer parent)
8486
_context = new ContainerContext(this);
8587

8688
// Caches
87-
OnStrategiesChanged(this, null);
8889
_strategies.Invalidated += OnStrategiesChanged;
8990
}
9091

@@ -95,6 +96,12 @@ private UnityContainer(UnityContainer parent)
9596

9697
protected void InitializeRootContainer()
9798
{
99+
// Initialize strategies
100+
_strategies = new StagedStrategyChain<IBuilderStrategy, UnityBuildStage>();
101+
_buildPlanStrategies = new StagedStrategyChain<IBuilderStrategy, BuilderStage>();
102+
_lifetimeContainer.Add(_strategies);
103+
_lifetimeContainer.Add(_buildPlanStrategies);
104+
98105
// Main strategy chain
99106
_strategies.Add(new BuildKeyMappingStrategy(), UnityBuildStage.TypeMapping);
100107
_strategies.Add(new LifetimeStrategy(), UnityBuildStage.Lifetime);
@@ -116,6 +123,10 @@ protected void InitializeRootContainer()
116123
this[typeof(IEnumerable<>), string.Empty, typeof(IBuildPlanCreatorPolicy)] =
117124
new DelegateBasedBuildPlanCreatorPolicy(typeof(UnityContainer).GetTypeInfo().GetDeclaredMethod(nameof(ResolveEnumerable)),
118125
context => context.BuildKey.Type.GetTypeInfo().GenericTypeArguments.First());
126+
// Caches
127+
_registerTypeStrategies = _strategies.OfType<IRegisterTypeStrategy>().ToArray();
128+
_strategyChain = new StrategyChain(_strategies);
129+
119130
// Register this instance
120131
RegisterInstance(typeof(IUnityContainer), null, this, new ContainerLifetimeManager());
121132
}

src/UnityContainer.Public.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Reflection;
5+
using Unity.Builder;
6+
using Unity.Builder.Strategy;
57
using Unity.Events;
68
using Unity.Extension;
79
using Unity.Policy;
@@ -83,8 +85,9 @@ public IUnityContainer RemoveAllExtensions()
8385
_extensions.Clear();
8486

8587
// Reset our policies, strategies, and registered names to reset to "zero"
86-
_strategies.Clear();
87-
((IPolicyList)_context).ClearAll();
88+
_strategies = new StagedStrategyChain<IBuilderStrategy, UnityBuildStage>(_parent?._strategies);
89+
90+
_context.ClearAll();
8891

8992
if (null == _parent)
9093
InitializeRootContainer();

0 commit comments

Comments
 (0)