Skip to content

Commit

Permalink
couple minor tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
david-driscoll committed Jun 1, 2019
1 parent 328cf02 commit 6ccf157
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 110 deletions.
1 change: 0 additions & 1 deletion src/Conventions/Composer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ class ComposerImpl<TContext, TContribution, TDelegate> : ConventionComposer<TCon
/// <typeparam name="TContribution"></typeparam>
/// <typeparam name="TDelegate"></typeparam>
/// <param name="scanner"></param>
/// <param name="logger"></param>
/// <param name="context"></param>
public static void Register<TContext, TContribution, TDelegate>(
IConventionScanner scanner,
Expand Down
109 changes: 0 additions & 109 deletions src/Conventions/ConventionComposer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,118 +3,11 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.Logging;
using Rocket.Surgery.Conventions;
using Rocket.Surgery.Conventions.Scanners;

namespace Rocket.Surgery.Conventions
{
public abstract class ConventionComposerBase
{
protected void ExecuteRegister(IConventionContext context, List<DelegateOrConvention> items, IEnumerable<Type> types)
{
var enumerable = types as Type[] ?? types.ToArray();
if (enumerable.Length == 0) return;

var delegateTypes = enumerable.Where(typeof(Delegate).IsAssignableFrom).ToArray();
var conventionTypes = enumerable.Except(delegateTypes).ToArray();

context.Logger.LogDebug("Found {Count} conventions or delegates", items.Count);

foreach (var itemWithIndex in items.Select((item, index) => new { item, index }))
{
var item = itemWithIndex.item;
try
{

if (item.Convention != null)
{
if (!conventionTypes.Any(type => type.IsInstanceOfType(item.Convention)))
{
context.Logger.LogDebug("Could not execute Convention {TypeName} from {AssemblyName} :: {@Types}",
item.Convention?.GetType()?.FullName,
item.Convention?.GetType()?.GetTypeInfo()?.Assembly?.GetName()?.Name,
enumerable);
continue;
}

context.Logger.LogDebug("Executing Convention {TypeName} from {AssemblyName}",
item.Convention?.GetType()?.FullName,
item.Convention?.GetType()?.GetTypeInfo()?.Assembly?.GetName()?.Name);
Register(item.Convention, context);
continue;
}

// ReSharper disable once UseNullPropagation
// ReSharper disable once InvertIf
if (item.Delegate != null)
{
if (!delegateTypes.Any(type => type.IsInstanceOfType(item.Delegate)))
{
context.Logger.LogDebug("Could not execute Delegate {TypeName} :: {@Types}",
item.Delegate.GetType()?.FullName,
enumerable);
continue;
}

context.Logger.LogDebug("Executing Delegate {TypeName}", item.Delegate.GetType()?.FullName);
item.Delegate.DynamicInvoke(context);
continue;
}

context.Logger.LogError("Convention or Delegate not available for one of the items");
}
catch (Exception e)
{
if (item.Convention != null)
context.Logger.LogError(0, e, "Error invoking Convention {Convention}", item.Convention?.GetType()?.FullName);
else if (item.Delegate != null)
context.Logger.LogError(0, e, "Error invoking Delegate at index {Index}", itemWithIndex.index);
else
context.Logger.LogError("Unknown error invoking Convention or Delegate at index {Index}", itemWithIndex.index);
throw;
}
}
}

private readonly ConcurrentDictionary<Type, MethodInfo> _registerMethodCache = new ConcurrentDictionary<Type, MethodInfo>();

private static readonly MethodInfo RegisterGenericMethod =
typeof(ConventionComposerBase).GetTypeInfo().GetDeclaredMethod(nameof(RegisterGeneric));

private void Register(IConvention convention, IConventionContext context)
{
var interfaces = convention.GetType().GetTypeInfo().ImplementedInterfaces
.Where(x => x.GetTypeInfo().IsGenericType)
.Where(x => x.GetTypeInfo().GetGenericTypeDefinition() == typeof(IConvention<>))
.Select(x => new { interfaceType = x, contextType = x.GetTypeInfo().GenericTypeArguments[0] });

var contextTypes = context.GetType().GetTypeInfo().ImplementedInterfaces
.Where(x => typeof(IConventionContext).IsAssignableFrom(x));

var typesToRegister = interfaces
.Join(contextTypes, x => x.contextType, x => x, (interfaceType, contextType) => contextType);

foreach (var item in typesToRegister)
{
if (!_registerMethodCache.TryGetValue(item, out var method))
{
method = RegisterGenericMethod.MakeGenericMethod(item);
_registerMethodCache.TryAdd(item, method);
}

method.Invoke(this, new object[] { convention, context });
}
}

private void RegisterGeneric<T>(IConvention<T> convention, T context)
where T : IConventionContext
{
convention.Register(context);
}
}


/// <summary>
/// Convention base compose, that calls all methods on register.
/// </summary>
Expand All @@ -132,7 +25,6 @@ public abstract class ConventionComposer<TContext, TContribution, TDelegate> : C
/// A base compose that does the composing of conventions and delegates
/// </summary>
/// <param name="scanner"></param>
/// <param name="logger"></param>
protected ConventionComposer(IConventionScanner scanner)
{
if (!typeof(Delegate).GetTypeInfo().IsAssignableFrom(typeof(TDelegate).GetTypeInfo()))
Expand Down Expand Up @@ -162,7 +54,6 @@ public class ConventionComposer : ConventionComposerBase, IConventionComposer
/// A base compose that does the composing of conventions and delegates
/// </summary>
/// <param name="scanner"></param>
/// <param name="logger"></param>
public ConventionComposer(IConventionScanner scanner)
{
_scanner = scanner;
Expand Down
115 changes: 115 additions & 0 deletions src/Conventions/ConventionComposerBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.Logging;
using Rocket.Surgery.Conventions.Scanners;

namespace Rocket.Surgery.Conventions
{
public abstract class ConventionComposerBase
{
protected void ExecuteRegister(IConventionContext context, List<DelegateOrConvention> items, IEnumerable<Type> types)
{
var enumerable = types as Type[] ?? types.ToArray();
if (enumerable.Length == 0) return;

var delegateTypes = enumerable.Where(typeof(Delegate).IsAssignableFrom).ToArray();
var conventionTypes = enumerable.Except(delegateTypes).ToArray();

context.Logger.LogDebug("Found {Count} conventions or delegates", items.Count);

foreach (var itemWithIndex in items.Select((item, index) => new { item, index }))
{
var item = itemWithIndex.item;
try
{

if (item.Convention != null)
{
if (!conventionTypes.Any(type => type.IsInstanceOfType(item.Convention)))
{
context.Logger.LogDebug("Could not execute Convention {TypeName} from {AssemblyName} :: {@Types}",
item.Convention?.GetType()?.FullName,
item.Convention?.GetType()?.GetTypeInfo()?.Assembly?.GetName()?.Name,
enumerable);
continue;
}

context.Logger.LogDebug("Executing Convention {TypeName} from {AssemblyName}",
item.Convention?.GetType()?.FullName,
item.Convention?.GetType()?.GetTypeInfo()?.Assembly?.GetName()?.Name);
Register(item.Convention, context);
continue;
}

// ReSharper disable once UseNullPropagation
// ReSharper disable once InvertIf
if (item.Delegate != null)
{
if (!delegateTypes.Any(type => type.IsInstanceOfType(item.Delegate)))
{
context.Logger.LogDebug("Could not execute Delegate {TypeName} :: {@Types}",
item.Delegate.GetType()?.FullName,
enumerable);
continue;
}

context.Logger.LogDebug("Executing Delegate {TypeName}", item.Delegate.GetType()?.FullName);
item.Delegate.DynamicInvoke(context);
continue;
}

context.Logger.LogError("Convention or Delegate not available for one of the items");
}
catch (Exception e)
{
if (item.Convention != null)
context.Logger.LogError(0, e, "Error invoking Convention {Convention}", item.Convention?.GetType()?.FullName);
else if (item.Delegate != null)
context.Logger.LogError(0, e, "Error invoking Delegate at index {Index}", itemWithIndex.index);
else
context.Logger.LogError("Unknown error invoking Convention or Delegate at index {Index}", itemWithIndex.index);
throw;
}
}
}

private readonly ConcurrentDictionary<Type, MethodInfo> _registerMethodCache = new ConcurrentDictionary<Type, MethodInfo>();

private static readonly MethodInfo RegisterGenericMethod =
typeof(ConventionComposerBase).GetTypeInfo().GetDeclaredMethod(nameof(RegisterGeneric));

private void Register(IConvention convention, IConventionContext context)
{
var interfaces = convention.GetType().GetTypeInfo().ImplementedInterfaces
.Where(x => x.GetTypeInfo().IsGenericType)
.Where(x => x.GetTypeInfo().GetGenericTypeDefinition() == typeof(IConvention<>))
.Select(x => new { interfaceType = x, contextType = x.GetTypeInfo().GenericTypeArguments[0] });

var contextTypes = context.GetType().GetTypeInfo().ImplementedInterfaces
.Where(x => typeof(IConventionContext).IsAssignableFrom(x));

var typesToRegister = interfaces
.Join(contextTypes, x => x.contextType, x => x, (interfaceType, contextType) => contextType);

foreach (var item in typesToRegister)
{
if (!_registerMethodCache.TryGetValue(item, out var method))
{
method = RegisterGenericMethod.MakeGenericMethod(item);
_registerMethodCache.TryAdd(item, method);
}

method.Invoke(this, new object[] { convention, context });
}
}

private void RegisterGeneric<T>(IConvention<T> convention, T context)
where T : IConventionContext
{
convention.Register(context);
}
}
}

0 comments on commit 6ccf157

Please sign in to comment.