using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using BLToolkit.Common;
using BLToolkit.ComponentModel;
using BLToolkit.EditableObjects;
using BLToolkit.Mapping;
using BLToolkit.TypeBuilder;
using BLToolkit.TypeBuilder.Builders;
using JNotNull = JetBrains.Annotations.NotNullAttribute;
namespace BLToolkit.Reflection
{
public delegate object NullValueProvider(Type type);
public delegate bool IsNullHandler (object obj);
[DebuggerDisplay("Type = {Type}, OriginalType = {OriginalType}")]
public abstract class TypeAccessor : ICollection, ITypeDescriptionProvider
{
#region Protected Emit Helpers
protected MemberInfo GetMember(int memberType, string memberName)
{
const BindingFlags allInstaceMembers =
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
MemberInfo mi;
switch (memberType)
{
case 1: mi = Type.GetField (memberName, allInstaceMembers); break;
case 2:
mi =
Type. GetProperty(memberName, allInstaceMembers) ??
OriginalType.GetProperty(memberName, allInstaceMembers);
break;
default:
throw new InvalidOperationException();
}
return mi;
}
protected void AddMember(MemberAccessor member)
{
if (member == null) throw new ArgumentNullException("member");
_members.Add(member);
_memberNames.Add(member.MemberInfo.Name, member);
}
#endregion
#region CreateInstance
[DebuggerStepThrough]
public virtual object CreateInstance()
{
throw new TypeBuilderException(string.Format(
"The '{0}' type must have public default or init constructor.",
OriginalType.Name));
}
[DebuggerStepThrough]
public virtual object CreateInstance(InitContext context)
{
return CreateInstance();
}
[DebuggerStepThrough]
public object CreateInstanceEx()
{
return _objectFactory != null?
_objectFactory.CreateInstance(this, null): CreateInstance((InitContext)null);
}
[DebuggerStepThrough]
public object CreateInstanceEx(InitContext context)
{
return _objectFactory != null? _objectFactory.CreateInstance(this, context): CreateInstance(context);
}
#endregion
#region ObjectFactory
private IObjectFactory _objectFactory;
public IObjectFactory ObjectFactory
{
get { return _objectFactory; }
set { _objectFactory = value; }
}
#endregion
#region Copy & AreEqual
internal static object CopyInternal(object source, object dest, TypeAccessor ta)
{
bool isDirty = false;
IMemberwiseEditable sourceEditable = source as IMemberwiseEditable;
IMemberwiseEditable destEditable = dest as IMemberwiseEditable;
if (sourceEditable != null && destEditable != null)
{
foreach (MemberAccessor ma in ta)
{
ma.CloneValue(source, dest);
if (sourceEditable.IsDirtyMember(null, ma.MemberInfo.Name, ref isDirty) && !isDirty)
destEditable.AcceptMemberChanges(null, ma.MemberInfo.Name);
}
}
else
{
foreach (MemberAccessor ma in ta)
ma.CloneValue(source, dest);
}
return dest;
}
public static object Copy(object source, object dest)
{
if (source == null) throw new ArgumentNullException("source");
if (dest == null) throw new ArgumentNullException("dest");
TypeAccessor ta;
Type sType = source.GetType();
Type dType = dest. GetType();
if (TypeHelper.IsSameOrParent(sType, dType)) ta = GetAccessor(sType);
else if (TypeHelper.IsSameOrParent(dType, sType)) ta = GetAccessor(dType);
else
throw new ArgumentException();
return CopyInternal(source, dest, ta);
}
public static object Copy(object source)
{
if (source == null) throw new ArgumentNullException("source");
TypeAccessor ta = GetAccessor(source.GetType());
return CopyInternal(source, ta.CreateInstanceEx(), ta);
}
public static bool AreEqual(object obj1, object obj2)
{
if (ReferenceEquals(obj1, obj2))
return true;
if (obj1 == null || obj2 == null)
return false;
TypeAccessor ta;
Type sType = obj1.GetType();
Type dType = obj2.GetType();
if (TypeHelper.IsSameOrParent(sType, dType)) ta = GetAccessor(sType);
else if (TypeHelper.IsSameOrParent(dType, sType)) ta = GetAccessor(dType);
else
return false;
foreach (MemberAccessor ma in ta)
if ((!Equals(ma.GetValue(obj1), ma.GetValue(obj2))))
return false;
return true;
}
public static int GetHashCode(object obj)
{
if (obj == null)
throw new ArgumentNullException("obj");
int hash = 0;
object value;
foreach (MemberAccessor ma in GetAccessor(obj.GetType()))
{
value = ma.GetValue(obj);
hash = ((hash << 5) + hash) ^ (value == null ? 0 : value.GetHashCode());
}
return hash;
}
#endregion
#region Abstract Members
public abstract Type Type { get; }
public abstract Type OriginalType { get; }
#endregion
#region Items
private readonly ArrayList _members = new ArrayList();
private readonly Hashtable _memberNames = new Hashtable();
public MemberAccessor this[string memberName]
{
get { return (MemberAccessor)_memberNames[memberName]; }
}
public MemberAccessor this[int index]
{
get { return (MemberAccessor)_members[index]; }
}
public MemberAccessor this[NameOrIndexParameter nameOrIndex]
{
get
{
return (MemberAccessor)
(nameOrIndex.ByName ? _memberNames[nameOrIndex.Name] : _members[nameOrIndex.Index]);
}
}
#endregion
#region Static Members
[Obsolete("Use TypeFactory.LoadTypes instead")]
public static bool LoadTypes
{
get { return TypeFactory.LoadTypes; }
set { TypeFactory.LoadTypes = value; }
}
private static readonly Hashtable _accessors = new Hashtable(10);
public static TypeAccessor GetAccessor(Type originalType)
{
if (originalType == null) throw new ArgumentNullException("originalType");
TypeAccessor accessor = (TypeAccessor)_accessors[originalType];
if (accessor == null)
{
lock (_accessors.SyncRoot)
{
accessor = (TypeAccessor)_accessors[originalType];
if (accessor == null)
{
if (IsAssociatedType(originalType))
return (TypeAccessor)_accessors[originalType];
Type instanceType = IsClassBulderNeeded(originalType)? null: originalType;
if (instanceType == null)
instanceType = TypeFactory.GetType(originalType);
Type accessorType = TypeFactory.GetType(originalType,
originalType, new TypeAccessorBuilder(instanceType, originalType));
accessor = (TypeAccessor)Activator.CreateInstance(accessorType);
_accessors[originalType] = accessor;
if (originalType != instanceType)
_accessors[instanceType] = accessor;
}
}
}
return accessor;
}
public static TypeAccessor GetAccessor([JNotNull] object obj)
{
if (obj == null) throw new ArgumentNullException("obj");
return GetAccessor(obj.GetType());
}
public static TypeAccessor GetAccessor<T>()
{
return TypeAccessor<T>.Instance;
}
private static bool IsClassBulderNeeded(Type type)
{
if (type.IsAbstract && !type.IsSealed)
{
if (!type.IsInterface)
{
if (TypeHelper.GetDefaultConstructor(type) != null)
return true;
if (TypeHelper.GetConstructor(type, typeof(InitContext)) != null)
return true;
}
else
{
object[] attrs = TypeHelper.GetAttributes(type, typeof(AutoImplementInterfaceAttribute));
if (attrs != null && attrs.Length > 0)
return true;
}
}
return false;
}
internal static bool IsInstanceBuildable(Type type)
{
if (!type.IsInterface)
return true;
lock (_accessors.SyncRoot)
{
if (_accessors[type] != null)
return true;
if (IsAssociatedType(type))
return true;
}
object[] attrs = TypeHelper.GetAttributes(type, typeof(AutoImplementInterfaceAttribute));
return attrs != null && attrs.Length > 0;
}
private static bool IsAssociatedType(Type type)
{
if (AssociatedTypeHandler != null)
{
Type child = AssociatedTypeHandler(type);
if (child != null)
{
AssociateType(type, child);
return true;
}
}
return false;
}
public static object CreateInstance(Type type)
{
return GetAccessor(type).CreateInstance();
}
public static object CreateInstance(Type type, InitContext context)
{
return GetAccessor(type).CreateInstance(context);
}
public static object CreateInstanceEx(Type type)
{
return GetAccessor(type).CreateInstanceEx();
}
public static object CreateInstanceEx(Type type, InitContext context)
{
return GetAccessor(type).CreateInstance(context);
}
public static T CreateInstance<T>()
{
return TypeAccessor<T>.CreateInstance();
}
public static T CreateInstance<T>(InitContext context)
{
return TypeAccessor<T>.CreateInstance(context);
}
public static T CreateInstanceEx<T>()
{
return TypeAccessor<T>.CreateInstanceEx();
}
public static T CreateInstanceEx<T>(InitContext context)
{
return TypeAccessor<T>.CreateInstance(context);
}
public static TypeAccessor AssociateType(Type parent, Type child)
{
if (!TypeHelper.IsSameOrParent(parent, child))
throw new ArgumentException(
string.Format("'{0}' must be a base type of '{1}'", parent, child),
"child");
TypeAccessor accessor = GetAccessor(child);
accessor = (TypeAccessor)Activator.CreateInstance(accessor.GetType());
lock (_accessors.SyncRoot)
_accessors[parent] = accessor;
return accessor;
}
public delegate Type GetAssociatedType(Type parent);
public static event GetAssociatedType AssociatedTypeHandler;
#endregion
#region GetNullValue
private static NullValueProvider _getNullValue = GetNullInternal;
public static NullValueProvider GetNullValue
{
get { return _getNullValue ?? (_getNullValue = GetNullInternal);}
set { _getNullValue = value; }
}
private static object GetNullInternal(Type type)
{
if (type == null) throw new ArgumentNullException("type");
if (type.IsValueType)
{
if (type.IsEnum)
return GetEnumNullValue(type);
if (type.IsPrimitive)
{
if (type == typeof(Int32)) return Common.Configuration.NullableValues.Int32;
if (type == typeof(Double)) return Common.Configuration.NullableValues.Double;
if (type == typeof(Int16)) return Common.Configuration.NullableValues.Int16;
if (type == typeof(Boolean)) return Common.Configuration.NullableValues.Boolean;
if (type == typeof(SByte)) return Common.Configuration.NullableValues.SByte;
if (type == typeof(Int64)) return Common.Configuration.NullableValues.Int64;
if (type == typeof(Byte)) return Common.Configuration.NullableValues.Byte;
if (type == typeof(UInt16)) return Common.Configuration.NullableValues.UInt16;
if (type == typeof(UInt32)) return Common.Configuration.NullableValues.UInt32;
if (type == typeof(UInt64)) return Common.Configuration.NullableValues.UInt64;
if (type == typeof(Single)) return Common.Configuration.NullableValues.Single;
if (type == typeof(Char)) return Common.Configuration.NullableValues.Char;
}
else
{
if (type == typeof(DateTime)) return Common.Configuration.NullableValues.DateTime;
#if FW3
if (type == typeof(DateTimeOffset)) return Common.Configuration.NullableValues.DateTimeOffset;
#endif
if (type == typeof(Decimal)) return Common.Configuration.NullableValues.Decimal;
if (type == typeof(Guid)) return Common.Configuration.NullableValues.Guid;
if (type == typeof(SqlInt32)) return SqlInt32. Null;
if (type == typeof(SqlString)) return SqlString. Null;
if (type == typeof(SqlBoolean)) return SqlBoolean. Null;
if (type == typeof(SqlByte)) return SqlByte. Null;
if (type == typeof(SqlDateTime)) return SqlDateTime.Null;
if (type == typeof(SqlDecimal)) return SqlDecimal. Null;
if (type == typeof(SqlDouble)) return SqlDouble. Null;
if (type == typeof(SqlGuid)) return SqlGuid. Null;
if (type == typeof(SqlInt16)) return SqlInt16. Null;
if (type == typeof(SqlInt64)) return SqlInt64. Null;
if (type == typeof(SqlMoney)) return SqlMoney. Null;
if (type == typeof(SqlSingle)) return SqlSingle. Null;
if (type == typeof(SqlBinary)) return SqlBinary. Null;
}
}
else
{
if (type == typeof(String)) return Common.Configuration.NullableValues.String;
if (type == typeof(DBNull)) return DBNull.Value;
if (type == typeof(Stream)) return Stream.Null;
if (type == typeof(SqlXml)) return SqlXml.Null;
}
return null;
}
const FieldAttributes EnumField = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal;
private static readonly Hashtable _nullValues = new Hashtable();
private static object GetEnumNullValue(Type type)
{
object nullValue = _nullValues[type];
if (nullValue != null || _nullValues.Contains(type))
return nullValue;
FieldInfo[] fields = type.GetFields();
foreach (FieldInfo fi in fields)
{
if ((fi.Attributes & EnumField) == EnumField)
{
Attribute[] attrs = Attribute.GetCustomAttributes(fi, typeof(NullValueAttribute));
if (attrs.Length > 0)
{
nullValue = Enum.Parse(type, fi.Name);
break;
}
}
}
_nullValues[type] = nullValue;
return nullValue;
}
private static IsNullHandler _isNull = IsNullInternal;
public static IsNullHandler IsNull
{
get { return _isNull ?? (_isNull = IsNullInternal); }
set { _isNull = value; }
}
private static bool IsNullInternal(object value)
{
if (value == null)
return true;
object nullValue = GetNullValue(value.GetType());
return nullValue != null && value.Equals(nullValue);
}
#endregion
#region ICollection Members
public void CopyTo(Array array, int index)
{
_members.CopyTo(array, index);
}
public int Count
{
get { return _members.Count; }
}
public bool IsSynchronized
{
get { return _members.IsSynchronized; }
}
public object SyncRoot
{
get { return _members.SyncRoot; }
}
public int IndexOf(MemberAccessor ma)
{
return _members.IndexOf(ma);
}
#endregion
#region IEnumerable Members
public IEnumerator GetEnumerator()
{
return _members.GetEnumerator();
}
#endregion
#region Write Object Info
public static void WriteDebug(object o)
{
#if DEBUG
Write(o, DebugWriteLine);
#endif
}
private static void DebugWriteLine(string text)
{
Debug.WriteLine(text);
}
public static void WriteConsole(object o)
{
Write(o, Console.WriteLine);
}
[SuppressMessage("Microsoft.Performance", "CA1818:DoNotConcatenateStringsInsideLoops")]
private static string MapTypeName(Type type)
{
if (type.IsGenericType)
{
if (type.GetGenericTypeDefinition() == typeof(Nullable<>))
return string.Format("{0}?", MapTypeName(Nullable.GetUnderlyingType(type)));
string name = type.Name;
int idx = name.IndexOf('`');
if (idx >= 0)
name = name.Substring(0, idx);
name += "<";
foreach (Type t in type.GetGenericArguments())
name += MapTypeName(t) + ',';
if (name[name.Length - 1] == ',')
name = name.Substring(0, name.Length - 1);
name += ">";
return name;
}
if (type.IsPrimitive ||
type == typeof(string) ||
type == typeof(object) ||
type == typeof(decimal))
{
if (type == typeof(int)) return "int";
if (type == typeof(bool)) return "bool";
if (type == typeof(short)) return "short";
if (type == typeof(long)) return "long";
if (type == typeof(ushort)) return "ushort";
if (type == typeof(uint)) return "uint";
if (type == typeof(ulong)) return "ulong";
if (type == typeof(float)) return "float";
return type.Name.ToLower();
}
return type.Name;
}
public delegate void WriteLine(string text);
[SuppressMessage("Microsoft.Usage", "CA2241:ProvideCorrectArgumentsToFormattingMethods")]
public static void Write(object o, WriteLine writeLine)
{
if (o == null)
{
writeLine("*** (null) ***");
return;
}
TypeAccessor ta = GetAccessor(o.GetType());
MemberAccessor ma;
int nameLen = 0;
int typeLen = 0;
foreach (DictionaryEntry de in ta._memberNames)
{
if (nameLen < de.Key.ToString().Length)
nameLen = de.Key.ToString().Length;
ma = (MemberAccessor)de.Value;
if (typeLen < MapTypeName(ma.Type).Length)
typeLen = MapTypeName(ma.Type).Length;
}
string text = "*** " + o.GetType().FullName + ": ***";
writeLine(text);
string format = string.Format("{{0,-{0}}} {{1,-{1}}} : {{2}}", typeLen, nameLen);
foreach (DictionaryEntry de in ta._memberNames)
{
ma = (MemberAccessor)de.Value;
object value = ma.GetValue(o);
if (value == null)
value = "(null)";
else if (value is ICollection)
value = string.Format("(Count = {0})", ((ICollection)value).Count);
text = string.Format(format, MapTypeName(ma.Type), de.Key, value);
writeLine(text);
}
writeLine("***");
}
#endregion
#region CustomTypeDescriptor
private static readonly Hashtable _descriptors = new Hashtable();
public static ICustomTypeDescriptor GetCustomTypeDescriptor(Type type)
{
ICustomTypeDescriptor descriptor = (ICustomTypeDescriptor)_descriptors[type];
if (descriptor == null)
{
lock (_descriptors.SyncRoot)
{
descriptor = (ICustomTypeDescriptor)_descriptors[type];
if (descriptor == null)
{
descriptor = new CustomTypeDescriptorImpl(type);
_descriptors.Add(type, descriptor);
}
}
}
return descriptor;
}
private ICustomTypeDescriptor _customTypeDescriptor;
public ICustomTypeDescriptor CustomTypeDescriptor
{
get
{
if (_customTypeDescriptor == null)
_customTypeDescriptor = GetCustomTypeDescriptor(OriginalType);
return _customTypeDescriptor;
}
}
#endregion
#region Property Descriptors
private PropertyDescriptorCollection _propertyDescriptors;
public PropertyDescriptorCollection PropertyDescriptors
{
get
{
if (_propertyDescriptors == null)
{
if (TypeHelper.IsSameOrParent(typeof(ICustomTypeDescriptor), OriginalType))
{
ICustomTypeDescriptor descriptor = CreateInstance() as ICustomTypeDescriptor;
if (descriptor != null)
_propertyDescriptors = descriptor.GetProperties();
}
if (_propertyDescriptors == null)
_propertyDescriptors = CreatePropertyDescriptors();
}
return _propertyDescriptors;
}
}
public PropertyDescriptorCollection CreatePropertyDescriptors()
{
Debug.WriteLineIf(BLToolkit.Data.DbManager.TraceSwitch.TraceInfo,
OriginalType.FullName, "CreatePropertyDescriptors");
PropertyDescriptor[] pd = new PropertyDescriptor[Count];
int i = 0;
foreach (MemberAccessor ma in _members)
pd[i++] = ma.PropertyDescriptor;
return new PropertyDescriptorCollection(pd);
}
public PropertyDescriptorCollection CreateExtendedPropertyDescriptors(
Type objectViewType,
IsNullHandler isNull)
{
// This is definitely wrong.
//
//if (isNull == null)
// isNull = _isNull;
PropertyDescriptorCollection pdc;
pdc = CreatePropertyDescriptors();
if (objectViewType != null)
{
TypeAccessor viewAccessor = GetAccessor(objectViewType);
IObjectView objectView = (IObjectView)viewAccessor.CreateInstanceEx();
List<PropertyDescriptor> list = new List<PropertyDescriptor>();
PropertyDescriptorCollection viewpdc = viewAccessor.PropertyDescriptors;
foreach (PropertyDescriptor pd in viewpdc)
list.Add(new ObjectViewPropertyDescriptor(pd, objectView));
foreach (PropertyDescriptor pd in pdc)
if (viewpdc.Find(pd.Name, false) == null)
list.Add(pd);
pdc = new PropertyDescriptorCollection(list.ToArray());
}
pdc = pdc.Sort(new PropertyDescriptorComparer());
pdc = GetExtendedProperties(pdc, OriginalType, String.Empty, Type.EmptyTypes, new PropertyDescriptor[0], isNull);
return pdc;
}
private static PropertyDescriptorCollection GetExtendedProperties(
PropertyDescriptorCollection pdc,
Type itemType,
string propertyPrefix,
Type[] parentTypes,
PropertyDescriptor[] parentAccessors,
IsNullHandler isNull)
{
ArrayList list = new ArrayList(pdc.Count);
ArrayList objects = new ArrayList();
bool isDataRow = itemType.IsSubclassOf(typeof(DataRow));
foreach (PropertyDescriptor p in pdc)
{
Type propertyType = p.PropertyType;
if (p.Attributes.Matches(BindableAttribute.No) ||
//propertyType == typeof(Type) ||
isDataRow && p.Name == "ItemArray")
continue;
bool isList = false;
bool explicitlyBound = p.Attributes.Contains(BindableAttribute.Yes);
PropertyDescriptor pd = p;
if (propertyType.GetInterface("IList") != null)
{
//if (!explicitlyBound)
// continue;
isList = true;
pd = new ListPropertyDescriptor(pd);
}
if (!isList &&
!propertyType.IsValueType &&
!propertyType.IsArray &&
(!propertyType.FullName.StartsWith("System.") || explicitlyBound
|| propertyType.IsGenericType) &&
propertyType != typeof(Type) &&
propertyType != typeof(string) &&
propertyType != typeof(object) &&
Array.IndexOf(parentTypes, propertyType) == -1)
{
Type[] childParentTypes = new Type[parentTypes.Length + 1];
parentTypes.CopyTo(childParentTypes, 0);
childParentTypes[parentTypes.Length] = itemType;
PropertyDescriptor[] childParentAccessors = new PropertyDescriptor[parentAccessors.Length + 1];
parentAccessors.CopyTo(childParentAccessors, 0);
childParentAccessors[parentAccessors.Length] = pd;
PropertyDescriptorCollection pdch = GetAccessor(propertyType).PropertyDescriptors;
pdch = pdch.Sort(new PropertyDescriptorComparer());
pdch = GetExtendedProperties(
pdch,
propertyType,
propertyPrefix + pd.Name + "+",
childParentTypes,
childParentAccessors,
isNull);
objects.AddRange(pdch);
}
else
{
if (propertyPrefix.Length != 0 || isNull != null)
pd = new StandardPropertyDescriptor(pd, propertyPrefix, parentAccessors, isNull);
list.Add(pd);
}
}
list.AddRange(objects);
return new PropertyDescriptorCollection(
(PropertyDescriptor[])list.ToArray(typeof(PropertyDescriptor)));
}
#region PropertyDescriptorComparer
class PropertyDescriptorComparer : IComparer
{
public int Compare(object x, object y)
{
return String.Compare(((PropertyDescriptor)x).Name, ((PropertyDescriptor)y).Name);
}
}
#endregion
#region ListPropertyDescriptor
class ListPropertyDescriptor : PropertyDescriptorWrapper
{
public ListPropertyDescriptor(PropertyDescriptor descriptor)
: base(descriptor)
{
}
public override object GetValue(object component)
{
object value = base.GetValue(component);
if (value == null)
return value;
if (value is IBindingList && value is ITypedList)
return value;
return EditableArrayList.Adapter((IList)value);
}
}
#endregion
#region StandardPropertyDescriptor
class StandardPropertyDescriptor : PropertyDescriptorWrapper
{
protected readonly PropertyDescriptor _descriptor = null;
protected readonly IsNullHandler _isNull;
protected readonly string _prefixedName;
protected readonly PropertyDescriptor[] _chainAccessors;
public StandardPropertyDescriptor(
PropertyDescriptor pd,
string namePrefix,
PropertyDescriptor[] chainAccessors,
IsNullHandler isNull)
: base(pd)
{
_descriptor = pd;
_isNull = isNull;
_prefixedName = namePrefix + pd.Name;
_chainAccessors = chainAccessors;
}
protected object GetNestedComponent(object component)
{
for (int i = 0;
i < _chainAccessors.Length && component != null && !(component is DBNull);
i++)
{
component = _chainAccessors[i].GetValue(component);
}
return component;
}
public override void SetValue(object component, object value)
{
component = GetNestedComponent(component);
if (component != null && !(component is DBNull))
_descriptor.SetValue(component, value);
}
public override object GetValue(object component)
{
component = GetNestedComponent(component);
return CheckNull(
component != null && !(component is DBNull)? _descriptor.GetValue(component): null);
}
public override string Name
{
get { return _prefixedName; }
}
protected object CheckNull(object value)
{
if (_isNull != null && _isNull(value))
{
switch (Common.Configuration.CheckNullReturnIfNull)
{
case Common.Configuration.NullEquivalent.DBNull:
return DBNull.Value;
case Common.Configuration.NullEquivalent.Null:
return null;
case Common.Configuration.NullEquivalent.Value:
return value;
}
return DBNull.Value;
}
return value;
}
}
#endregion
#region objectViewPropertyDescriptor
class ObjectViewPropertyDescriptor : PropertyDescriptorWrapper
{
public ObjectViewPropertyDescriptor(PropertyDescriptor pd, IObjectView objectView)
: base(pd)
{
_objectView = objectView;
}
private readonly IObjectView _objectView;
public override object GetValue(object component)
{
_objectView.Object = component;
return base.GetValue(_objectView);
}
public override void SetValue(object component, object value)
{
_objectView.Object = component;
base.SetValue(_objectView, value);
}
}
#endregion
#endregion
#region ITypeDescriptionProvider Members
string ITypeDescriptionProvider.ClassName
{
get { return OriginalType.Name; }
}
string ITypeDescriptionProvider.ComponentName
{
get { return OriginalType.Name; }
}
EventDescriptor ITypeDescriptionProvider.GetEvent(string name)
{
return new CustomEventDescriptor(OriginalType.GetEvent(name));
}
PropertyDescriptor ITypeDescriptionProvider.GetProperty(string name)
{
MemberAccessor ma = this[name];
return ma != null ? ma.PropertyDescriptor : null;
}
AttributeCollection ITypeDescriptionProvider.GetAttributes()
{
return new AttributeCollection((Attribute[])new TypeHelper(OriginalType).GetAttributes());
}
EventDescriptorCollection ITypeDescriptionProvider.GetEvents()
{
EventInfo[] ei = OriginalType.GetEvents();
EventDescriptor[] ed = new EventDescriptor[ei.Length];
for (int i = 0; i < ei.Length; i++)
ed[i] = new CustomEventDescriptor(ei[i]);
return new EventDescriptorCollection(ed);
}
PropertyDescriptorCollection ITypeDescriptionProvider.GetProperties()
{
return CreatePropertyDescriptors();
}
#region CustomEventDescriptor
class CustomEventDescriptor : EventDescriptor
{
public CustomEventDescriptor(EventInfo eventInfo)
: base(eventInfo.Name, null)
{
_eventInfo = eventInfo;
}
private readonly EventInfo _eventInfo;
public override void AddEventHandler(object component, Delegate value)
{
_eventInfo.AddEventHandler(component, value);
}
public override void RemoveEventHandler(object component, Delegate value)
{
_eventInfo.RemoveEventHandler(component, value);
}
public override Type ComponentType { get { return _eventInfo.DeclaringType; } }
public override Type EventType { get { return _eventInfo.EventHandlerType; } }
public override bool IsMulticast { get { return _eventInfo.IsMulticast; } }
}
#endregion
#endregion
}
} |