ln.types/odb/ClassMapping.cs

110 lines
3.1 KiB
C#

using System;
using ln.types.odb.values;
using System.Reflection;
using System.Collections.Generic;
using ln.logging;
namespace ln.types.odb
{
public class DocumentIDAttribute : Attribute
{
}
public class ClassMapping : IODBMapping
{
public Type MappedType { get; }
public String IDField { get; private set; }
List<FieldInfo> mappedFields = new List<FieldInfo>();
public ClassMapping(Type type)
{
Logging.Log(LogLevel.DEBUG, "Constructing ClassMapping for {0}",type);
MappedType = type;
AddFields(type);
}
private void AddFields(Type type)
{
foreach (FieldInfo fieldinfo in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
{
if (fieldinfo.GetCustomAttribute<IgnoreFieldAttribute>() == null)
{
mappedFields.Add(fieldinfo);
if (fieldinfo.GetCustomAttribute<DocumentIDAttribute>() != null)
{
IDField = fieldinfo.Name;
}
}
}
if ((type != null) && !type.IsValueType && (!typeof(object).Equals(type.BaseType)))
{
AddFields(type.BaseType);
}
}
public object UnmapValue(ODBMapper mapper,ODBValue oval)
{
ODBDocument document = oval as ODBDocument;
object o = Activator.CreateInstance(MappedType, true);
foreach (FieldInfo fieldInfo in mappedFields)
{
object fv = ODBMapper.Default.UnmapValue(fieldInfo.FieldType,document[fieldInfo.Name]);
fieldInfo.SetValue(o, fv);
}
return o;
}
public ODBValue MapValue(ODBMapper mapper,object value)
{
ODBDocument document = new ODBDocument();
document["__asm__"] = value.GetType().Assembly.GetName().Name;
document["__type__"] = value.GetType().FullName;
foreach (FieldInfo fieldInfo in mappedFields)
{
object fv = fieldInfo.GetValue(value);
ODBValue ov = ODBMapper.Default.MapValue(fv);
document[fieldInfo.Name] = ov;
}
if (IDField != null)
{
document.ID = document[IDField];
}
return document;
}
}
public class ObjectMapping : IODBMapping
{
public ODBValue MapValue(ODBMapper mapper, object value)
{
return new ODBDocument();
}
public object UnmapValue(ODBMapper mapper, ODBValue oval)
{
if (oval is ODBDocument)
{
ODBDocument document = oval.AsDocument;
if (!document.Contains("__type__"))
return new object();
Type dType = Assembly.Load(document["__asm__"].AsString).GetType(document["__type__"].AsString);
return mapper.UnmapValue(dType, oval);
}
else
{
return oval.Value;
}
}
}
}