Skip to content

Commit fe9c1c7

Browse files
committed
Added caches
1 parent 52e77d2 commit fe9c1c7

File tree

3 files changed

+40
-21
lines changed

3 files changed

+40
-21
lines changed

src/ObjectBuilder/Strategies/BuildKeyMappingStrategy.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,29 +35,26 @@ public override object PreBuildUp(IBuilderContext context)
3535
public void RegisterType(IContainerContext context, Type typeFrom, Type typeTo, string name,
3636
LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
3737
{
38-
var buildType = typeFrom ?? typeTo;
39-
4038
if (null == typeFrom || typeFrom == typeTo)
4139
{
42-
context.Policies.Clear(buildType, name, typeof(IBuildKeyMappingPolicy));
40+
context.Policies.Clear(typeTo, name, typeof(IBuildKeyMappingPolicy));
4341
return;
4442
}
4543

46-
var buildKey = new NamedTypeBuildKey(buildType, name);
47-
4844
if (typeFrom.GetTypeInfo().IsGenericTypeDefinition && typeTo.GetTypeInfo().IsGenericTypeDefinition)
4945
{
5046
context.Policies.Set<IBuildKeyMappingPolicy>(new GenericTypeBuildKeyMappingPolicy(new NamedTypeBuildKey(typeTo, name)),
5147
new NamedTypeBuildKey(typeFrom, name));
5248
}
5349
else
5450
{
55-
context.Policies.Set<IBuildKeyMappingPolicy>(new BuildKeyMappingPolicy(new NamedTypeBuildKey(typeTo, name)), buildKey);
51+
context.Policies.Set(typeFrom, name, typeof(IBuildKeyMappingPolicy),
52+
new BuildKeyMappingPolicy(new NamedTypeBuildKey(typeTo, name)));
5653
}
5754

5855
var members = null == injectionMembers ? new InjectionMember[0] : injectionMembers;
5956
if (!members.Where(m => m is InjectionConstructor || m is InjectionMethod || m is InjectionProperty).Any() && !(lifetimeManager is IRequireBuildUpPolicy))
60-
context.Policies.Set<IBuildPlanPolicy>(new ResolveBuildUpPolicy(), buildKey);
57+
context.Policies.Set(typeFrom, name, typeof(IBuildPlanPolicy), new ResolveBuildUpPolicy());
6158
}
6259
}
6360
}

src/UnityContainer.Implementation.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Globalization;
4+
using System.Linq;
45
using System.Reflection;
56
using Unity.Builder;
67
using Unity.Builder.Strategy;
@@ -37,6 +38,9 @@ public partial class UnityContainer
3738
private event EventHandler<RegisterInstanceEventArgs> RegisteringInstance;
3839
private event EventHandler<ChildContainerCreatedEventArgs> ChildContainerCreated;
3940

41+
// Caches
42+
private IRegisterTypeStrategy[] _registerTypeStrategies;
43+
4044
#endregion
4145

4246

@@ -63,6 +67,10 @@ private UnityContainer(UnityContainer parent)
6367

6468
if (null == _parent) InitializeStrategies();
6569

70+
// Caches
71+
OnStrategiesChanged(this, null);
72+
_strategies.Invalidated += OnStrategiesChanged;
73+
6674
RegisterInstance(typeof(IUnityContainer), null, this, new ContainerLifetimeManager());
6775
}
6876

@@ -128,6 +136,20 @@ private void SetLifetimeManager(Type lifetimeType, string name, LifetimeManager
128136

129137
#region Implementation
130138

139+
private UnityContainer GetRootContainer()
140+
{
141+
UnityContainer container;
142+
143+
for (container = this; container._parent != null; container = container._parent) ;
144+
145+
return container;
146+
}
147+
148+
private void OnStrategiesChanged(object sender, EventArgs e)
149+
{
150+
_registerTypeStrategies = _strategies.OfType<IRegisterTypeStrategy>().ToArray();
151+
}
152+
131153
/// <summary>
132154
/// Verifies that an argument instance is assignable from the provided type (meaning
133155
/// interfaces are implemented, or classes exist in the base class hierarchy, or instance can be

src/UnityContainer.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,13 @@ public IUnityContainer RegisterType(Type typeFrom, Type typeTo, string name,
7070

7171
// Register Type
7272
var buildType = typeFrom ?? typeTo;
73+
var container = (lifetimeManager is ISingletonLifetimePolicy) ? GetRootContainer() : this;
7374

7475
// Clear build plan
75-
_policies.Set(buildType, name, typeof(IBuildPlanPolicy), new OverriddenBuildPlanMarkerPolicy());
76+
container._policies.Set(buildType, name, typeof(IBuildPlanPolicy), new OverriddenBuildPlanMarkerPolicy());
7677

7778
// Register Type/Name
78-
_registeredNames.RegisterType(buildType, name);
79+
container._registeredNames.RegisterType(buildType, name);
7980

8081
// Add Injection Members to the list
8182
if (null != injectionMembers && injectionMembers.Length > 0)
@@ -85,17 +86,17 @@ public IUnityContainer RegisterType(Type typeFrom, Type typeTo, string name,
8586
if (member is IInjectionFactory && null != typeFrom && typeFrom != typeTo)
8687
throw new InvalidOperationException(Constants.CannotInjectFactory);
8788

88-
member.AddPolicies(buildType, typeTo, name, _policies);
89+
member.AddPolicies(buildType, typeTo, name, container._policies);
8990
}
9091
}
9192

9293
// Register policies for each strategy
93-
// TODO: Use cached version to impreve performance
94-
foreach (var strategy in _strategies.OfType<IRegisterTypeStrategy>())
94+
var strategies = container._registerTypeStrategies;
95+
foreach (var strategy in strategies)
9596
strategy.RegisterType(_context, typeFrom, typeTo, name, lifetimeManager, injectionMembers);
9697

9798
// Raise event
98-
Registering?.Invoke(this, new RegisterEventArgs(typeFrom, typeTo, name, lifetimeManager));
99+
container.Registering?.Invoke(this, new RegisterEventArgs(typeFrom, typeTo, name, lifetimeManager));
99100

100101
return this;
101102
}
@@ -132,21 +133,20 @@ public IUnityContainer RegisterInstance(Type toType, string name, object instanc
132133

133134
var type = toType ?? instance.GetType();
134135
var lifetime = manager ?? new ContainerControlledLifetimeManager();
136+
var container = (manager is ISingletonLifetimePolicy) ? GetRootContainer() : this;
135137

136-
_registeredNames.RegisterType(type, name);
138+
container._registeredNames.RegisterType(type, name);
137139

138140
lifetime.SetValue(instance);
139-
SetLifetimeManager(type, name, lifetime);
141+
container.SetLifetimeManager(type, name, lifetime);
140142

141143
if (lifetime is IBuildPlanPolicy buildPlanPolicy)
142-
_policies.Set(type, name, typeof(IBuildPlanPolicy), buildPlanPolicy);
144+
container._policies.Set(type, name, typeof(IBuildPlanPolicy), buildPlanPolicy);
143145
else
144-
_policies.Set(type, name, typeof(IBuildPlanPolicy), new OverriddenBuildPlanMarkerPolicy());
146+
container._policies.Set(type, name, typeof(IBuildPlanPolicy), new OverriddenBuildPlanMarkerPolicy());
145147

146-
RegisteringInstance?.Invoke(this, new RegisterInstanceEventArgs(type,
147-
instance,
148-
name,
149-
lifetime));
148+
container.RegisteringInstance?.Invoke(this, new RegisterInstanceEventArgs(type, instance,
149+
name, lifetime));
150150
return this;
151151
}
152152

0 commit comments

Comments
 (0)