Add ln.types.reflection
parent
a008409bce
commit
b02d62c4cb
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
namespace ln.types.attributes
|
||||
{
|
||||
public class IdentityAttribute : Attribute
|
||||
{
|
||||
public IdentityAttribute()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -139,6 +139,15 @@
|
|||
<Compile Include="test\SchedulingPoolTests.cs" />
|
||||
<Compile Include="text\TokenReader.cs" />
|
||||
<Compile Include="io\LineWriter.cs" />
|
||||
<Compile Include="reflection\AttributeDescriptor.cs" />
|
||||
<Compile Include="reflection\TypeDescriptor.cs" />
|
||||
<Compile Include="reflection\Reflector.cs" />
|
||||
<Compile Include="reflection\ReflectedValue.cs" />
|
||||
<Compile Include="collections\IDict.cs" />
|
||||
<Compile Include="reflection\ObjectPoolContainer.cs" />
|
||||
<Compile Include="reflection\ObjectPool.cs" />
|
||||
<Compile Include="attributes\IdentityAttribute.cs" />
|
||||
<Compile Include="reflection\ObjectPoolValue.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="odb\" />
|
||||
|
@ -163,6 +172,8 @@
|
|||
<Folder Include="odb\ng\diff\" />
|
||||
<Folder Include="io\" />
|
||||
<Folder Include="text\" />
|
||||
<Folder Include="reflection\" />
|
||||
<Folder Include="attributes\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ln.logging\ln.logging.csproj">
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
// /**
|
||||
// * File: AttributeDescriptor.cs
|
||||
// * Author: haraldwolff
|
||||
// *
|
||||
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
||||
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
||||
// *
|
||||
// *
|
||||
// **/
|
||||
using System;
|
||||
using System.Reflection;
|
||||
namespace ln.types.reflection
|
||||
{
|
||||
public class AttributeDescriptor
|
||||
{
|
||||
public bool IsPublic { get; }
|
||||
public bool IsReadonly { get; }
|
||||
|
||||
public Type Owner { get; }
|
||||
public string AttributeName { get; }
|
||||
public Type AttributeType { get; }
|
||||
|
||||
Action<object, object> SetAction;
|
||||
Func<object, object> GetFunc;
|
||||
|
||||
public AttributeDescriptor(PropertyInfo propertyInfo)
|
||||
{
|
||||
Owner = propertyInfo.DeclaringType;
|
||||
IsPublic = propertyInfo.GetGetMethod().IsPublic;
|
||||
IsReadonly = !(propertyInfo.CanWrite && propertyInfo.GetSetMethod().IsPublic);
|
||||
AttributeName = propertyInfo.Name;
|
||||
AttributeType = propertyInfo.PropertyType;
|
||||
|
||||
SetAction = propertyInfo.SetValue;
|
||||
GetFunc = propertyInfo.GetValue;
|
||||
}
|
||||
public AttributeDescriptor(FieldInfo fieldInfo)
|
||||
{
|
||||
Owner = fieldInfo.DeclaringType;
|
||||
IsPublic = fieldInfo.IsPublic;
|
||||
IsReadonly = fieldInfo.IsInitOnly;
|
||||
AttributeName = fieldInfo.Name;
|
||||
AttributeType = fieldInfo.FieldType;
|
||||
|
||||
SetAction = fieldInfo.SetValue;
|
||||
GetFunc = fieldInfo.GetValue;
|
||||
}
|
||||
|
||||
public TypeDescriptor TypeDescriptor => TypeDescriptor.GetDescriptor(Owner);
|
||||
|
||||
public object GetValue(object instance) => GetFunc(instance);
|
||||
public void SetValue(object instance, object value) => SetAction(instance, value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using ln.types.btree;
|
||||
using System.Collections.Generic;
|
||||
namespace ln.types.reflection
|
||||
{
|
||||
public class ObjectPool
|
||||
{
|
||||
public Type ObjectType { get; }
|
||||
public Type IdentityType { get; }
|
||||
|
||||
public TypeDescriptor TypeDescriptor => TypeDescriptor.GetDescriptor(ObjectType);
|
||||
|
||||
Func<object, object> getIdentity;
|
||||
public object GetIdentity(object o) => getIdentity(o);
|
||||
|
||||
BTree<object, object> objects = new BTree<object, object>();
|
||||
|
||||
List<ObjectPool> derivedTypes = new List<ObjectPool>();
|
||||
|
||||
public ObjectPool(Type objectType, Type identityType, Func<object, object> getIdentityDelegate)
|
||||
{
|
||||
ObjectType = objectType;
|
||||
IdentityType = identityType;
|
||||
getIdentity = getIdentityDelegate;
|
||||
}
|
||||
|
||||
public IEnumerable<object> Identities => objects.Keys;
|
||||
public IEnumerable<object> Instances => objects.Values;
|
||||
|
||||
public object this[object identity] => objects[identity];
|
||||
|
||||
public void Add(object o) => objects.Add(GetIdentity(o), o);
|
||||
public void Remove(object identity) => objects.Remove(identity);
|
||||
|
||||
|
||||
public ObjectPoolValue GetValue(string attributePath) => throw new NotImplementedException();
|
||||
|
||||
public void AddDerivedTypePool(ObjectPool objectPool) => derivedTypes.Add(objectPool);
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
using System;
|
||||
using ln.types.btree;
|
||||
using System.Reflection;
|
||||
using ln.types.attributes;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
namespace ln.types.reflection
|
||||
{
|
||||
public class ObjectPoolContainer
|
||||
{
|
||||
BTree<string, ObjectPool> objectPools = new BTree<string, ObjectPool>();
|
||||
public IEnumerable<ObjectPool> Pools => objectPools.Values;
|
||||
public IEnumerable<Type> Types => objectPools.Values.Select((pool) => pool.ObjectType);
|
||||
|
||||
public ObjectPoolContainer()
|
||||
{
|
||||
}
|
||||
|
||||
public ObjectPool this[string typeName] => objectPools[typeName];
|
||||
public ObjectPool this[Type type] => objectPools[type.Name];
|
||||
|
||||
public ObjectPoolContainer AddType(Type type) => AddType(type, null);
|
||||
public ObjectPoolContainer AddType(Type type,String identityAttribute)
|
||||
{
|
||||
foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
||||
{
|
||||
if (((identityAttribute == null) && (fieldInfo.GetCustomAttribute<IdentityAttribute>()!=null)) || fieldInfo.Name.Equals(identityAttribute))
|
||||
{
|
||||
objectPools.Add(type.Name, new ObjectPool(type, fieldInfo.FieldType, fieldInfo.GetValue));
|
||||
}
|
||||
}
|
||||
foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
||||
{
|
||||
if (((identityAttribute == null) && (propertyInfo.GetCustomAttribute<IdentityAttribute>() != null)) || propertyInfo.Name.Equals(identityAttribute))
|
||||
{
|
||||
objectPools.Add(type.Name, new ObjectPool(type, propertyInfo.PropertyType, propertyInfo.GetValue));
|
||||
}
|
||||
}
|
||||
|
||||
SetupDerivedTypes(type);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void SetupDerivedTypes(Type type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
namespace ln.types.reflection
|
||||
{
|
||||
public class ObjectPoolValue
|
||||
{
|
||||
public ObjectPool ObjectPool { get; }
|
||||
public object Value { get; }
|
||||
|
||||
public string[] PathElements { get; }
|
||||
public string Path => String.Join("/", PathElements);
|
||||
|
||||
public ObjectPoolValue(ObjectPool objectPool,string[] pathElements,object value)
|
||||
{
|
||||
ObjectPool = objectPool;
|
||||
PathElements = pathElements;
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
|
||||
namespace ln.types.reflection
|
||||
{
|
||||
public class ReflectedValue
|
||||
{
|
||||
public ReflectedValue ReflectedOwner { get; }
|
||||
public object Owner { get; }
|
||||
|
||||
public AttributeDescriptor AttributeDescriptor { get; }
|
||||
public object Value { get; private set; }
|
||||
|
||||
public ReflectedValue(object owner, string attributeName)
|
||||
{
|
||||
Owner = owner;
|
||||
AttributeDescriptor = TypeDescriptor.GetDescriptor(Owner.GetType()).GetAttributeDescriptor(attributeName);
|
||||
Value = AttributeDescriptor.GetValue(Owner);
|
||||
}
|
||||
public ReflectedValue(ReflectedValue reflectedOwner, string attributeName)
|
||||
{
|
||||
ReflectedOwner = reflectedOwner;
|
||||
Owner = reflectedOwner.Value;
|
||||
AttributeDescriptor = TypeDescriptor.GetDescriptor(Owner.GetType()).GetAttributeDescriptor(attributeName);
|
||||
Value = AttributeDescriptor.GetValue(Owner);
|
||||
}
|
||||
|
||||
public virtual void Replace(object value)
|
||||
{
|
||||
AttributeDescriptor.SetValue(Owner, value);
|
||||
Value = value;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
namespace ln.types.reflection
|
||||
{
|
||||
public static class Reflector
|
||||
{
|
||||
|
||||
public static void Get(object o, string path, out Type type, out object value)
|
||||
{
|
||||
Queue<string> pElements = new Queue<string>(path.Split('/'));
|
||||
type = o.GetType();
|
||||
|
||||
while (pElements.Count > 0)
|
||||
{
|
||||
GetValue(o, pElements.Dequeue(), out type, out o);
|
||||
}
|
||||
value = o;
|
||||
}
|
||||
public static void Set(object o, string path, object value)
|
||||
{
|
||||
Queue<string> pElements = new Queue<string>(path.Split('/'));
|
||||
Type valueType = null;
|
||||
|
||||
while (pElements.Count > 1)
|
||||
{
|
||||
GetValue(o, pElements.Dequeue(), out valueType, out o);
|
||||
}
|
||||
|
||||
SetValue(o, pElements.Dequeue(), value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void GetValue(object o, string attributeName,out Type valueType, out object value)
|
||||
{
|
||||
TypeDescriptor typeDescriptor = TypeDescriptor.GetDescriptor(o.GetType());
|
||||
AttributeDescriptor attributeDescriptor = typeDescriptor.GetAttributeDescriptor(attributeName);
|
||||
valueType = attributeDescriptor.AttributeType;
|
||||
value = attributeDescriptor.GetValue(o);
|
||||
}
|
||||
public static void SetValue(object o, string attributeName, object value)
|
||||
{
|
||||
TypeDescriptor typeDescriptor = TypeDescriptor.GetDescriptor(o.GetType());
|
||||
typeDescriptor.GetAttributeDescriptor(attributeName).SetValue(o, value);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public static ReflectedValue[] Walk(object o,string path)
|
||||
{
|
||||
List<ReflectedValue> reflectedValues = new List<ReflectedValue>();
|
||||
|
||||
foreach (string pathElement in path.Split('/'))
|
||||
{
|
||||
ReflectedValue reflectedValue = new ReflectedValue(o, pathElement);
|
||||
o = reflectedValue.Value;
|
||||
reflectedValues.Add(reflectedValue);
|
||||
}
|
||||
|
||||
return reflectedValues.ToArray();
|
||||
}
|
||||
|
||||
|
||||
public static object GetValue(object o, string path) => GetValue(o, new Queue<string>(path.Split('/')));
|
||||
public static object GetValue(object o, Queue<string> path)
|
||||
{
|
||||
while (path.Count > 0)
|
||||
o = GetNext(o, path.Dequeue());
|
||||
return o;
|
||||
}
|
||||
public static object SetValue(object o, string path, object value) => SetValue(o, new Queue<string>(path.Split('/')), value);
|
||||
public static object SetValue(object o, Queue<string> path, object value)
|
||||
{
|
||||
while (path.Count > 1)
|
||||
o = GetNext(o, path.Dequeue());
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
public static object GetNext(object o, string next)
|
||||
{
|
||||
if (o is Array)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetAttributeValue(o, next);
|
||||
}
|
||||
}
|
||||
public static void SetNext(object o, string next, object value)
|
||||
{
|
||||
if (o is Array)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetAttributeValue(o, next, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// /**
|
||||
// * File: TypeDescriptor.cs
|
||||
// * Author: haraldwolff
|
||||
// *
|
||||
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
||||
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
||||
// *
|
||||
// *
|
||||
// **/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
namespace ln.types.reflection
|
||||
{
|
||||
public class TypeDescriptor
|
||||
{
|
||||
public Type Type { get; }
|
||||
|
||||
Dictionary<string, AttributeDescriptor> attributeDescriptors = new Dictionary<string, AttributeDescriptor>();
|
||||
|
||||
public TypeDescriptor(Type type)
|
||||
{
|
||||
typeDescriptors[type] = this;
|
||||
|
||||
foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public))
|
||||
attributeDescriptors.Add(fieldInfo.Name, new AttributeDescriptor(fieldInfo));
|
||||
|
||||
foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
|
||||
attributeDescriptors.Add(propertyInfo.Name, new AttributeDescriptor(propertyInfo));
|
||||
|
||||
}
|
||||
|
||||
public IEnumerable<string> AttributeNames => attributeDescriptors.Keys;
|
||||
public AttributeDescriptor GetAttributeDescriptor(string attributeName) => attributeDescriptors[attributeName];
|
||||
public bool ContainsAttribute(string attributeName) => attributeDescriptors.ContainsKey(attributeName);
|
||||
|
||||
static Dictionary<Type, TypeDescriptor> typeDescriptors = new Dictionary<Type, TypeDescriptor>();
|
||||
public static TypeDescriptor GetDescriptor(Type type)
|
||||
{
|
||||
if (typeDescriptors.TryGetValue(type, out TypeDescriptor typeDescriptor))
|
||||
return new TypeDescriptor(type);
|
||||
return typeDescriptor;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue