Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
Improve registry startup and lookup performance (#674)
Browse files Browse the repository at this point in the history
* Optimize search for Effect resolution name
Avoid multiple collection of assemblies during startup
Cache handler lookups

* Handle s_initialized check inside of Initialize method
  • Loading branch information
hartez authored and rmarinho committed Jan 12, 2017
1 parent 20ed60f commit 1616413
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 19 deletions.
18 changes: 16 additions & 2 deletions Xamarin.Forms.Core/DependencyService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ public static class DependencyService

public static T Get<T>(DependencyFetchTarget fetchTarget = DependencyFetchTarget.GlobalInstance) where T : class
{
if (!s_initialized)
Initialize();
Initialize();

Type targetType = typeof(T);

Expand Down Expand Up @@ -64,12 +63,27 @@ static Type FindImplementor(Type target)

static void Initialize()
{
if (s_initialized)
{
return;
}

Assembly[] assemblies = Device.GetAssemblies();
if (Registrar.ExtraAssemblies != null)
{
assemblies = assemblies.Union(Registrar.ExtraAssemblies).ToArray();
}

Initialize(assemblies);
}

internal static void Initialize(Assembly[] assemblies)
{
if (s_initialized)
{
return;
}

Type targetAttrType = typeof(DependencyAttribute);

// Don't use LINQ for performance reasons
Expand Down
43 changes: 26 additions & 17 deletions Xamarin.Forms.Core/Registrar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,18 @@ internal TOut GetHandler<TOut>(Type type) where TOut : TRegistrable

internal Type GetHandlerType(Type viewType)
{
Type type = LookupHandlerType(viewType);
if (type != null)
Type type;
if(LookupHandlerType(viewType, out type))
return type;

// lazy load render-view association with RenderWithAttribute (as opposed to using ExportRenderer)
// TODO: change Registrar to a LazyImmutableDictionary and pass this logic to ctor as a delegate.
var attribute = viewType.GetTypeInfo().GetCustomAttribute<RenderWithAttribute>();
if (attribute == null)
{
Register(viewType, null); // Cache this result so we don't have to do GetCustomAttribute again
return null;
}

type = attribute.Type;

if (type.Name.StartsWith("_"))
Expand All @@ -51,30 +54,33 @@ internal Type GetHandlerType(Type viewType)

if (type.Name.StartsWith("_"))
{
//var attrs = type.GetTypeInfo ().GetCustomAttributes ().ToArray ();
Register(viewType, null); // Cache this result so we don't work through this chain again
return null;
}
}

Register(viewType, type);
return LookupHandlerType(viewType);
Register(viewType, type); // Register this so we don't have to look for the RenderWith Attibute again in the future

return type;
}

Type LookupHandlerType(Type viewType)
bool LookupHandlerType(Type viewType, out Type handlerType)
{
Type type = viewType;

while (true)
while (type != null)
{
if (_handlers.ContainsKey(type))
return _handlers[type];
{
handlerType = _handlers[type];
return true;
}

type = type.GetTypeInfo().BaseType;
if (type == null)
break;
}

return null;
handlerType = null;
return false;
}
}

Expand Down Expand Up @@ -126,22 +132,25 @@ internal static void RegisterAll(Type[] attrTypes)
}

string resolutionName = assembly.FullName;
var resolutionNameAttribute = (ResolutionGroupNameAttribute)assembly.GetCustomAttribute(typeof(ResolutionGroupNameAttribute));
if (resolutionNameAttribute != null)
{
resolutionName = resolutionNameAttribute.ShortName;
}

Attribute[] effectAttributes = assembly.GetCustomAttributes(typeof(ExportEffectAttribute)).ToArray();
if (effectAttributes.Length > 0)
{
var resolutionNameAttribute = (ResolutionGroupNameAttribute)assembly.GetCustomAttribute(typeof(ResolutionGroupNameAttribute));
if (resolutionNameAttribute != null)
{
resolutionName = resolutionNameAttribute.ShortName;
}

foreach (Attribute attribute in effectAttributes)
{
var effect = (ExportEffectAttribute)attribute;
Effects [resolutionName + "." + effect.Id] = effect.Type;
}
}
}

DependencyService.Initialize(assemblies);
}
}
}

0 comments on commit 1616413

Please sign in to comment.