ln.http.resources/reflection/Reflector.cs
Harald Wolff e94811994f WIP
2019-04-05 00:59:02 +02:00

114 lines
3.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
using ln.http.exceptions;
using System.IO;
using System.Text;
namespace ln.http.resources.reflection
{
public class Reflector
{
Type TargetType { get; }
Dictionary<string, PropertyInfo> properties = new Dictionary<string, PropertyInfo>();
Dictionary<string, MethodInfo> methods = new Dictionary<string, MethodInfo>();
public Reflector(Type targetType)
{
TargetType = targetType;
Initialize();
}
private void Initialize()
{
foreach (PropertyInfo propertyInfo in TargetType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (propertyInfo.GetCustomAttribute<CallableAttribute>() != null)
{
properties.Add(propertyInfo.Name, propertyInfo);
}
}
foreach (MethodInfo methodInfo in TargetType.GetMethods(BindingFlags.Public | BindingFlags.Instance))
{
if (methodInfo.GetCustomAttribute<CallableAttribute>() != null)
{
methods.Add(methodInfo.Name, methodInfo);
}
}
}
public object InvokeRequest(HttpRequest httpRequest, Queue<string> pathStack, object currentValue)
{
if (pathStack.Count == 0)
return currentValue;
StringReader reader = new StringReader(pathStack.Dequeue());
StringBuilder sb = new StringBuilder();
while (IsValidNameChar((char)reader.Peek()))
sb.Append((char)reader.Read());
string next = sb.ToString();
sb.Clear();
if (properties.ContainsKey(next))
{
currentValue = properties[next].GetValue(currentValue);
}
else
{
throw new KeyNotFoundException(next);
}
while (reader.Peek() != -1)
{
char nc = (char)reader.Read();
switch (nc)
{
case '[':
while ((reader.Peek() != ']') && (reader.Peek() != -1))
sb.Append((char)reader.Read());
reader.Read();
string index = sb.ToString();
sb.Clear();
Type currentType = currentValue.GetType();
if (currentType.IsArray)
{
int i = int.Parse(index);
currentValue = ((Array)currentValue).GetValue(i);
}
else
{
throw new NotSupportedException();
}
break;
default:
throw new NotSupportedException();
}
}
return currentValue;
}
public static bool IsValidNameChar(char ch)
{
return Char.IsLetterOrDigit(ch) | (ch == '_');
}
static Dictionary<Type, Reflector> reflectorsCache = new Dictionary<Type, Reflector>();
public static Reflector GetReflector(Type targetType)
{
if (!reflectorsCache.ContainsKey(targetType))
{
reflectorsCache[targetType] = new Reflector(targetType);
}
return reflectorsCache[targetType];
}
}
}