private ObjectMemberAccessor(Type type)
{
/*
if ( !TypeUtils.IsPublic(type) )
throw new ArgumentException(
"Can not serialize non-public type {0}.".DoFormat(type.FullName));
*/
const BindingFlags propertyFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.NonPublic;
// public properties
foreach ( var p in type.GetProperties(propertyFlags) ) {
var prop = p; // create closures with this local variable
// not readable or parameters required to access the property
if ( !prop.CanRead || prop.GetGetMethod(false) == null || prop.GetIndexParameters().Count() != 0 )
continue;
Func<object, object> get = ReflectionUtils.CreateGetPropertyMethod(prop);
Action<object, object> set = ReflectionUtils.CreateSetPropertyMethod(prop);
RegisterMember(type, prop, prop.PropertyType, get, set);
}
const BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetField | BindingFlags.NonPublic;
// public fields
foreach ( var f in type.GetFields(fieldFlags) ) {
var field = f;
Func<object, object> get = ReflectionUtils.CreateGetFieldMethod(field);
Action<object, object> set = ReflectionUtils.CreateSetFieldMethod(field);
RegisterMember(type, field, field.FieldType, get, set);
}
Type itype;
// implements IDictionary
if ( type.GetInterface("System.Collections.IDictionary") != null ) {
IsDictionary = true;
IsReadOnly = obj => ( (System.Collections.IDictionary)obj ).IsReadOnly;
// extract Key, Value types from IDictionary<??, ??>
itype = type.GetInterface("System.Collections.Generic.IDictionary`2");
if ( itype != null ) {
KeyType = itype.GetGenericArguments()[0];
ValueType = itype.GetGenericArguments()[1];
}
} else
// implements ICollection<T>
if ( ( itype = type.GetInterface("System.Collections.Generic.ICollection`1") ) != null ) {
ValueType = itype.GetGenericArguments()[0];
var add = itype.GetMethod("Add", new Type[] { ValueType });
CollectionAdd = (obj, value) => add.Invoke(obj, new object[] { value });
var clear = itype.GetMethod("Clear", new Type[0]);
CollectionClear = obj => clear.Invoke(obj, new object[0]);
var isReadOnly = itype.GetProperty("IsReadOnly", new Type[0]).GetGetMethod();
IsReadOnly = obj => (bool)isReadOnly.Invoke(obj, new object[0]);
} else
// implements IList
if ( ( itype = type.GetInterface("System.Collections.IList") ) != null ) {
var add = itype.GetMethod("Add", new Type[] { typeof(object) });
CollectionAdd = (obj, value) => add.Invoke(obj, new object[] { value });
var clear = itype.GetMethod("Clear", new Type[0]);
CollectionClear = obj => clear.Invoke(obj, new object[0]);
/* IList<T> implements ICollection<T>
// Extract Value Type from IList<T>
itype = type.GetInterface("System.Collections.Generic.IList`1");
if ( itype != null )
ValueType = itype.GetGenericArguments()[0];
*/
IsReadOnly = obj => ((System.Collections.IList)obj).IsReadOnly;
}
}