Skip to content

Commit

Permalink
Added caches
Browse files Browse the repository at this point in the history
  • Loading branch information
ENikS committed Dec 30, 2017
1 parent 52e77d2 commit fe9c1c7
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 21 deletions.
11 changes: 4 additions & 7 deletions src/ObjectBuilder/Strategies/BuildKeyMappingStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,26 @@ public override object PreBuildUp(IBuilderContext context)
public void RegisterType(IContainerContext context, Type typeFrom, Type typeTo, string name,
LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
{
var buildType = typeFrom ?? typeTo;

if (null == typeFrom || typeFrom == typeTo)
{
context.Policies.Clear(buildType, name, typeof(IBuildKeyMappingPolicy));
context.Policies.Clear(typeTo, name, typeof(IBuildKeyMappingPolicy));
return;
}

var buildKey = new NamedTypeBuildKey(buildType, name);

if (typeFrom.GetTypeInfo().IsGenericTypeDefinition && typeTo.GetTypeInfo().IsGenericTypeDefinition)
{
context.Policies.Set<IBuildKeyMappingPolicy>(new GenericTypeBuildKeyMappingPolicy(new NamedTypeBuildKey(typeTo, name)),
new NamedTypeBuildKey(typeFrom, name));
}
else
{
context.Policies.Set<IBuildKeyMappingPolicy>(new BuildKeyMappingPolicy(new NamedTypeBuildKey(typeTo, name)), buildKey);
context.Policies.Set(typeFrom, name, typeof(IBuildKeyMappingPolicy),
new BuildKeyMappingPolicy(new NamedTypeBuildKey(typeTo, name)));
}

var members = null == injectionMembers ? new InjectionMember[0] : injectionMembers;
if (!members.Where(m => m is InjectionConstructor || m is InjectionMethod || m is InjectionProperty).Any() && !(lifetimeManager is IRequireBuildUpPolicy))
context.Policies.Set<IBuildPlanPolicy>(new ResolveBuildUpPolicy(), buildKey);
context.Policies.Set(typeFrom, name, typeof(IBuildPlanPolicy), new ResolveBuildUpPolicy());
}
}
}
22 changes: 22 additions & 0 deletions src/UnityContainer.Implementation.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Unity.Builder;
using Unity.Builder.Strategy;
Expand Down Expand Up @@ -37,6 +38,9 @@ public partial class UnityContainer
private event EventHandler<RegisterInstanceEventArgs> RegisteringInstance;
private event EventHandler<ChildContainerCreatedEventArgs> ChildContainerCreated;

// Caches
private IRegisterTypeStrategy[] _registerTypeStrategies;

#endregion


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

if (null == _parent) InitializeStrategies();

// Caches
OnStrategiesChanged(this, null);
_strategies.Invalidated += OnStrategiesChanged;

RegisterInstance(typeof(IUnityContainer), null, this, new ContainerLifetimeManager());
}

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

#region Implementation

private UnityContainer GetRootContainer()
{
UnityContainer container;

for (container = this; container._parent != null; container = container._parent) ;

return container;
}

private void OnStrategiesChanged(object sender, EventArgs e)
{
_registerTypeStrategies = _strategies.OfType<IRegisterTypeStrategy>().ToArray();
}

/// <summary>
/// Verifies that an argument instance is assignable from the provided type (meaning
/// interfaces are implemented, or classes exist in the base class hierarchy, or instance can be
Expand Down
28 changes: 14 additions & 14 deletions src/UnityContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ public IUnityContainer RegisterType(Type typeFrom, Type typeTo, string name,

// Register Type
var buildType = typeFrom ?? typeTo;
var container = (lifetimeManager is ISingletonLifetimePolicy) ? GetRootContainer() : this;

// Clear build plan
_policies.Set(buildType, name, typeof(IBuildPlanPolicy), new OverriddenBuildPlanMarkerPolicy());
container._policies.Set(buildType, name, typeof(IBuildPlanPolicy), new OverriddenBuildPlanMarkerPolicy());

// Register Type/Name
_registeredNames.RegisterType(buildType, name);
container._registeredNames.RegisterType(buildType, name);

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

member.AddPolicies(buildType, typeTo, name, _policies);
member.AddPolicies(buildType, typeTo, name, container._policies);
}
}

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

// Raise event
Registering?.Invoke(this, new RegisterEventArgs(typeFrom, typeTo, name, lifetimeManager));
container.Registering?.Invoke(this, new RegisterEventArgs(typeFrom, typeTo, name, lifetimeManager));

return this;
}
Expand Down Expand Up @@ -132,21 +133,20 @@ public IUnityContainer RegisterInstance(Type toType, string name, object instanc

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

_registeredNames.RegisterType(type, name);
container._registeredNames.RegisterType(type, name);

lifetime.SetValue(instance);
SetLifetimeManager(type, name, lifetime);
container.SetLifetimeManager(type, name, lifetime);

if (lifetime is IBuildPlanPolicy buildPlanPolicy)
_policies.Set(type, name, typeof(IBuildPlanPolicy), buildPlanPolicy);
container._policies.Set(type, name, typeof(IBuildPlanPolicy), buildPlanPolicy);
else
_policies.Set(type, name, typeof(IBuildPlanPolicy), new OverriddenBuildPlanMarkerPolicy());
container._policies.Set(type, name, typeof(IBuildPlanPolicy), new OverriddenBuildPlanMarkerPolicy());

RegisteringInstance?.Invoke(this, new RegisterInstanceEventArgs(type,
instance,
name,
lifetime));
container.RegisteringInstance?.Invoke(this, new RegisterInstanceEventArgs(type, instance,
name, lifetime));
return this;
}

Expand Down

0 comments on commit fe9c1c7

Please sign in to comment.