Created
June 21, 2017 07:36
-
-
Save thenameless314159/a5df5461f705c1bd2d981fb2afa16855 to your computer and use it in GitHub Desktop.
Simple predicat/method wrapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PartsManager<TP, T> | |
where TP : AbstractPart<T> | |
{ | |
private static Dictionary<TP, MethodInfo> PartMapper { get; } | |
static PartsManager() | |
{ | |
var ass = typeof(TP).Assembly; | |
var types = | |
ass.GetTypes() | |
.Where( | |
type => type.IsClass | |
&& !type.IsAbstract | |
&& type.IsAssignableFrom(typeof(TP))); | |
var parts = types.Select(type => (TP)Activator.CreateInstance(type)).ToImmutableList(); | |
PartMapper = new Dictionary<TP, MethodInfo>(parts.Count); | |
foreach(var p in parts) | |
PartMapper.Add(p, p.GetType().GetMethods().First(mi => mi.Name != "Predicat")); | |
} | |
public void ExecuteParts(T input, IEnumerable<object> handlerParameters) | |
{ | |
var haveParameters = CheckParameters(input, handlerParameters); | |
foreach (var pair in PartMapper) | |
{ | |
var part = pair.Key; | |
var handlerMi = pair.Value; | |
// Invoke method cost is high, but this is only used for run-time expr generation | |
if (!part.Predicat(input)) continue; | |
if (haveParameters) | |
{ | |
handlerMi.Invoke(part, new object[] { input }); | |
break; | |
} | |
var newSize = handlerParameters.Count() + 1; | |
var newParamList = new List<object>(newSize) {input}; | |
newParamList.AddRange(handlerParameters); | |
handlerMi.Invoke(part, newParamList.ToArray()); | |
break; | |
} | |
} | |
private bool CheckParameters(T input, IEnumerable<object> handlerParameters) | |
{ | |
Throw.IfNull(input, nameof(input)); | |
var handlersParameters = PartMapper.First().Value.GetParameters(); | |
if (!handlerParameters.Any()) | |
return false; | |
return PartMapper.All(pair => | |
pair.Value.GetParametersType().SequenceEqual(handlerParameters.Select(hp => hp.GetType()))); | |
} | |
} | |
public abstract class AbstractPart<T> | |
{ | |
public abstract bool Predicat(T param); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment