Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataWeb / Client / System / Data / Services / Client / ClientType.cs / 4 / ClientType.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // //// type resolver // //--------------------------------------------------------------------- namespace System.Data.Services.Client { using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Data.Services.Common; using System.Linq; ////// wrapper around a clr type to /// get/set properties /// add items to collections /// support open types /// [DebuggerDisplay("{ElementTypeName}")] internal sealed class ClientType { ///what is the clr full name using ToString for generic name expansion internal readonly string ElementTypeName; ///what clr type does this represent internal readonly Type ElementType; ///if HasKeys then EntityType else if !KnownType then ComplexType else PrimitiveType internal readonly bool HasKeys; ///count of keys on entity type internal readonly int KeyCount; #region static fields ///appdomain cache discovered types with properties that we materialize private static readonly Dictionarytypes = new Dictionary (); /// cache <T> and wireName to mapped type private static readonly DictionarynamedTypes = new Dictionary (new TypeNameEqualityComparer()); #endregion #if ASTORIA_OPEN_OBJECT /// IDictionary<string,object> OpenProperites { get; } private readonly ClientProperty openProperties; #endif ///properties private ArraySetproperties; /// Property that holds data for ATOM-style media link entries private ClientProperty mediaDataMember; ////// discover and prepare properties for usage /// /// type being processed /// parameter name /// Whether the skip the check for settable properties. private ClientType(Type type, string typeName, bool skipSettableCheck) { Debug.Assert(null != type, "null type"); Debug.Assert(!String.IsNullOrEmpty(typeName), "empty typeName"); this.ElementTypeName = typeName; this.ElementType = Nullable.GetUnderlyingType(type) ?? type; #if ASTORIA_OPEN_OBJECT string openObjectPropertyName = null; #endif if (!ClientConvert.IsKnownType(this.ElementType)) { #if ASTORIA_OPEN_OBJECT #region OpenObject determined by walking type hierarchy and looking for [OpenObjectAttribute("PropertyName")] Type openObjectDeclared = this.ElementType; for (Type tmp = openObjectDeclared; (null != tmp) && (typeof(object) != tmp); tmp = tmp.BaseType) { object[] attributes = openObjectDeclared.GetCustomAttributes(typeof(OpenObjectAttribute), false); if (1 == attributes.Length) { if (null != openObjectPropertyName) { throw Error.InvalidOperation(Strings.Clienttype_MultipleOpenProperty(this.ElementTypeName)); } openObjectPropertyName = ((OpenObjectAttribute)attributes[0]).OpenObjectPropertyName; openObjectDeclared = tmp; } } #endregion #endif Type keyPropertyDeclaredType = null; DataServiceKeyAttribute dska = type.GetCustomAttributes(true).OfType().FirstOrDefault(); foreach (PropertyInfo pinfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { //// examples where class //// the normal examples //// PropertyType Property { get; set } //// Nullable Property { get; set; } //// if 'Property: struct' then we would be unable set the property during construction (and have them stick) //// but when its a class, we can navigate if non-null and set the nested properties //// PropertyType Property { get; } where PropertyType: class //// we do support adding elements to collections //// ICollection { get; /*ignored set;*/ } //// indexed properties are not suported because //// we don't have anything to use as the index //// PropertyType Property[object x] { /*ignored get;*/ /*ignored set;*/ } //// also ignored //// if PropertyType.IsPointer (like byte*) //// if PropertyType.IsArray except for byte[] and char[] //// if PropertyType == IntPtr or UIntPtr Type ptype = pinfo.PropertyType; // class / interface / value ptype = Nullable.GetUnderlyingType(ptype) ?? ptype; if (ptype.IsPointer || (ptype.IsArray && (typeof(byte[]) != ptype) && typeof(char[]) != ptype) || (typeof(IntPtr) == ptype) || (typeof(UIntPtr) == ptype)) { continue; } Debug.Assert(!ptype.ContainsGenericParameters, "remove when test case is found that encounters this"); if (pinfo.CanRead && (!ptype.IsValueType || pinfo.CanWrite) && !ptype.ContainsGenericParameters && (0 == pinfo.GetIndexParameters().Length)) { #region IsKey? bool keyProperty = dska != null ? dska.KeyNames.Contains(pinfo.Name) : false; if (keyProperty) { if (null == keyPropertyDeclaredType) { keyPropertyDeclaredType = pinfo.DeclaringType; } else if (keyPropertyDeclaredType != pinfo.DeclaringType) { throw Error.InvalidOperation(Strings.ClientType_KeysOnDifferentDeclaredType(this.ElementTypeName)); } if (!ClientConvert.IsKnownType(ptype)) { throw Error.InvalidOperation(Strings.ClientType_KeysMustBeSimpleTypes(this.ElementTypeName)); } this.KeyCount++; } #endregion #if ASTORIA_OPEN_OBJECT #region IsOpenObjectProperty? bool openProperty = (openObjectPropertyName == pinfo.Name) && typeof(IDictionary ).IsAssignableFrom(ptype); Debug.Assert(keyProperty != openProperty || (!keyProperty && !openProperty), "key can't be open type"); #endregion ClientProperty property = new ClientProperty(pinfo, ptype, keyProperty, openProperty); if (!property.OpenObjectProperty) #else ClientProperty property = new ClientProperty(pinfo, ptype, keyProperty); #endif { if (!this.properties.Add(property, ClientProperty.NameEquality)) { // 2nd property with same name shadows another property int shadow = this.IndexOfProperty(property.PropertyName); if (!property.DeclaringType.IsAssignableFrom(this.properties[shadow].DeclaringType)) { // the new property is on the most derived class this.properties.RemoveAt(shadow); this.properties.Add(property, null); } } } #if ASTORIA_OPEN_OBJECT else { if (pinfo.DeclaringType == openObjectDeclared) { this.openProperties = property; } } #endif } } #region No KeyAttribute, discover key by name pattern { DeclaringType.Name+ID, ID } if (null == keyPropertyDeclaredType) { ClientProperty key = null; for (int i = this.properties.Count - 1; 0 <= i; --i) { string propertyName = this.properties[i].PropertyName; if (propertyName.EndsWith("ID", StringComparison.Ordinal)) { string declaringTypeName = this.properties[i].DeclaringType.Name; if ((propertyName.Length == (declaringTypeName.Length + 2)) && propertyName.StartsWith(declaringTypeName, StringComparison.Ordinal)) { // matched "DeclaringType.Name+ID" pattern if ((null == keyPropertyDeclaredType) || this.properties[i].DeclaringType.IsAssignableFrom(keyPropertyDeclaredType)) { keyPropertyDeclaredType = this.properties[i].DeclaringType; key = this.properties[i]; } } else if ((null == keyPropertyDeclaredType) && (2 == propertyName.Length)) { // matched "ID" pattern keyPropertyDeclaredType = this.properties[i].DeclaringType; key = this.properties[i]; } } } if (null != key) { Debug.Assert(0 == this.KeyCount, "shouldn't have a key yet"); key.KeyProperty = true; this.KeyCount++; } } else if (this.KeyCount != dska.KeyNames.Count) { var m = (from string a in dska.KeyNames where null == (from b in this.properties where b.PropertyName == a select b).FirstOrDefault() select a).First (); throw Error.InvalidOperation(Strings.ClientType_MissingProperty(this.ElementTypeName, m)); } #endregion this.HasKeys = (null != keyPropertyDeclaredType); Debug.Assert(this.KeyCount == this.Properties.Where(k => k.KeyProperty).Count(), "KeyCount mismatch"); this.WireUpMimeTypeProperties(); this.CheckMediaLinkEntry(); if (!skipSettableCheck) { #if ASTORIA_OPEN_OBJECT if ((0 == this.properties.Count) && (null == this.openProperties)) #else if (0 == this.properties.Count) #endif { // implicit construction? throw Error.InvalidOperation(Strings.ClientType_NoSettableFields(this.ElementTypeName)); } } } this.properties.Sort (ClientProperty.GetPropertyName, String.CompareOrdinal); #if ASTORIA_OPEN_OBJECT #region Validate OpenObjectAttribute was used if ((null != openObjectPropertyName) && (null == this.openProperties)) { throw Error.InvalidOperation(Strings.ClientType_MissingOpenProperty(this.ElementTypeName, openObjectPropertyName)); } Debug.Assert((null != openObjectPropertyName) == (null != this.openProperties), "OpenProperties mismatch"); #endregion #endif } /// Properties sorted by name internal ArraySetProperties { get { return this.properties; } } /// Property that holds data for ATOM-style media link entries internal ClientProperty MediaDataMember { get { return this.mediaDataMember; } } ////// get a client type resolver /// /// type to wrap ///client type internal static ClientType Create(Type type) { return Create(type, true /* expectModelType */); } ////// get a client type resolver /// /// type to wrap /// Whether the type is expected to be a model type. ///client type internal static ClientType Create(Type type, bool expectModelType) { ClientType clientType; lock (ClientType.types) { ClientType.types.TryGetValue(type, out clientType); } if (null == clientType) { bool skipSettableCheck = !expectModelType; clientType = new ClientType(type, type.ToString(), skipSettableCheck); // ToString expands generic type name where as FullName does not if (expectModelType) { lock (ClientType.types) { ClientType existing; if (ClientType.types.TryGetValue(type, out existing)) { clientType = existing; } else { ClientType.types.Add(type, clientType); } } } } return clientType; } #if !ASTORIA_LIGHT ////// resolve the wireName/userType pair to a CLR type /// /// type name sent by server /// type passed by user or on propertyType from a class ///mapped clr type internal static Type ResolveFromName(string wireName, Type userType) #else ////// resolve the wireName/userType pair to a CLR type /// /// type name sent by server /// type passed by user or on propertyType from a class /// typeof context for strongly typed assembly ///mapped clr type internal static Type ResolveFromName(string wireName, Type userType, Type contextType) #endif { Type foundType; TypeName typename; typename.Type = userType; typename.Name = wireName; lock (ClientType.namedTypes) { ClientType.namedTypes.TryGetValue(typename, out foundType); } if (null == foundType) { string name = wireName; int index = wireName.LastIndexOf('.'); if ((0 <= index) && (index < wireName.Length - 1)) { name = wireName.Substring(index + 1); } if (userType.Name == name) { foundType = userType; } else { #if !ASTORIA_LIGHT // searching only loaded assemblies, not referenced assemblies foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) #else foreach (Assembly assembly in new Assembly[] { userType.Assembly, contextType.Assembly }.Distinct()) #endif { Type found = assembly.GetType(wireName, false); ResolveSubclass(name, userType, found, ref foundType); if (null == found) { Type[] types = null; try { types = assembly.GetTypes(); } catch (ReflectionTypeLoadException) { } if (null != types) { foreach (Type t in types) { ResolveSubclass(name, userType, t, ref foundType); } } } } } if (null != foundType) { lock (ClientType.namedTypes) { ClientType.namedTypes[typename] = foundType; } } } return foundType; } ////// get concrete type that implements the genericTypeDefinitation /// /// starting type /// the generic type definition to find ///concrete type that implementats the generic type internal static Type GetImplementationType(Type propertyType, Type genericTypeDefinition) { if (IsConstructedGeneric(propertyType, genericTypeDefinition)) { // propertyType is ICollectionreturn propertyType; } else { Type implementationType = null; foreach (Type interfaceType in propertyType.GetInterfaces()) { if (IsConstructedGeneric(interfaceType, genericTypeDefinition)) { if (null == implementationType) { // found implmentation of ICollection implementationType = interfaceType; } else { // ICollection and ICollection throw Error.NotSupported(Strings.ClientType_MultipleImplementationNotSupported); } } } return implementationType; } } /// /// get element type, resolves ICollection and Nullable /// /// starting type /// the generic type definition to find /// the method to search for /// the collection type if found ///element types internal static MethodInfo GetCollectionMethod(Type propertyType, Type genericTypeDefinition, string methodName, out Type type) { Debug.Assert(null != propertyType, "null propertyType"); Debug.Assert(null != genericTypeDefinition, "null genericTypeDefinition"); Debug.Assert(genericTypeDefinition.IsGenericTypeDefinition, "!IsGenericTypeDefinition"); type = null; Type implementationType = GetImplementationType(propertyType, genericTypeDefinition); if (null != implementationType) { Type[] genericArguments = implementationType.GetGenericArguments(); MethodInfo methodInfo = implementationType.GetMethod(methodName); Debug.Assert(null != methodInfo, "should have found the method"); #if DEBUG Debug.Assert(null != genericArguments, "null genericArguments"); ParameterInfo[] parameters = methodInfo.GetParameters(); if (0 < parameters.Length) { // following assert was disabled for Contains which returns bool // Debug.Assert(typeof(void) == methodInfo.ReturnParameter.ParameterType, "method doesn't return void"); Debug.Assert(genericArguments.Length == parameters.Length, "genericArguments don't match parameters"); for (int i = 0; i < genericArguments.Length; ++i) { Debug.Assert(genericArguments[i] == parameters[i].ParameterType, "parameter doesn't match generic argument"); } } #endif type = genericArguments[genericArguments.Length - 1]; return methodInfo; } return null; } ////// create object using default constructor /// ///instance of propertyType internal object CreateInstance() { return Activator.CreateInstance(this.ElementType); } ////// get property wrapper for a property name, might be method around open types for otherwise unknown properties /// /// property name /// are missing properties ignored ///property wrapper ///for unknown properties on closed types internal ClientProperty GetProperty(string propertyName, bool ignoreMissingProperties) { int index = this.IndexOfProperty(propertyName); if (0 <= index) { return this.properties[index]; } #if ASTORIA_OPEN_OBJECT else if (null != this.openProperties) { return this.openProperties; } #endif else if (!ignoreMissingProperties) { throw Error.InvalidOperation(Strings.ClientType_MissingProperty(this.ElementTypeName, propertyName)); } return null; } ////// Checks whether the specified /// Type to check. /// Generic type for checkin. ///is a /// closed constructed type of the generic type. /// true if ///is a constructed type of . The check is an immediate check; no inheritance rules are applied. private static bool IsConstructedGeneric(Type type, Type genericTypeDefinition) { Debug.Assert(type != null, "type != null"); Debug.Assert(!type.ContainsGenericParameters, "remove when test case is found that encounters this"); Debug.Assert(genericTypeDefinition != null, "genericTypeDefinition != null"); return type.IsGenericType && (type.GetGenericTypeDefinition() == genericTypeDefinition) && !type.ContainsGenericParameters; } ////// is the type a visible subclass with correct name /// /// type name from server /// the type from user for materialization or property type /// type being tested /// the previously discovered matching type ///if the mapping is ambiguous private static void ResolveSubclass(string wireClassName, Type userType, Type type, ref Type existing) { if ((null != type) && type.IsVisible && (wireClassName == type.Name) && userType.IsAssignableFrom(type)) { if (null != existing) { throw Error.InvalidOperation(Strings.Deserialize_Current(existing, type)); } existing = type; } } ///get the index of a property /// propertyName ///index else -1 private int IndexOfProperty(string propertyName) { return this.properties.IndexOf(propertyName, ClientProperty.GetPropertyName, String.Equals); } ////// Find properties with dynamic MIME type related properties and /// set the references from each ClientProperty to its related MIME type property /// private void WireUpMimeTypeProperties() { MimeTypePropertyAttribute attribute = (MimeTypePropertyAttribute)this.ElementType.GetCustomAttributes(typeof(MimeTypePropertyAttribute), true).SingleOrDefault(); if (null != attribute) { int dataIndex, mimeTypeIndex; if ((0 > (dataIndex = this.IndexOfProperty(attribute.DataPropertyName))) || (0 > (mimeTypeIndex = this.IndexOfProperty(attribute.MimeTypePropertyName)))) { throw Error.InvalidOperation(Strings.ClientType_MissingMimeTypeProperty(attribute.DataPropertyName, attribute.MimeTypePropertyName)); } Debug.Assert(0 <= dataIndex, "missing data property"); Debug.Assert(0 <= mimeTypeIndex, "missing mime type property"); this.Properties[dataIndex].MimeTypeProperty = this.Properties[mimeTypeIndex]; } } ////// Check if this type represents an ATOM-style media link entry and /// if so mark the ClientType as such /// private void CheckMediaLinkEntry() { object[] attributes = this.ElementType.GetCustomAttributes(typeof(MediaEntryAttribute), true); if (attributes != null && attributes.Length > 0) { Debug.Assert(attributes.Length == 1, "The AttributeUsage in the attribute definition should be presenting more than 1 per property"); int index = this.IndexOfProperty(((MediaEntryAttribute)attributes[0]).MediaMemberName); if (index < 0) { throw Error.InvalidOperation(Strings.ClientType_MissingMediaEntryProperty( ((MediaEntryAttribute)attributes[0]).MediaMemberName)); } this.mediaDataMember = this.properties[index]; } } ///type + wireName combination private struct TypeName { ///type internal Type Type; ///type name from server internal string Name; } ////// wrapper around property methods /// [DebuggerDisplay("{PropertyName}")] internal sealed class ClientProperty { ///property name for debugging internal readonly string PropertyName; ///type of the property internal readonly Type NullablePropertyType; ///type of the property internal readonly Type PropertyType; ///what is the nested collection element internal readonly Type CollectionType; ////// Is this a known primitive/reference type or an entity/complex/collection type? /// internal readonly bool IsKnownType; #if ASTORIA_OPEN_OBJECT ///IDictionary<string,object> OpenProperites { get; } internal readonly bool OpenObjectProperty; #endif ///property getter private readonly MethodInfo propertyGetter; ///property setter private readonly MethodInfo propertySetter; ///"set_Item" method supporting IDictionary properties private readonly MethodInfo setMethod; ///"Add" method supporting ICollection<> properties private readonly MethodInfo addMethod; ///"Remove" method supporting ICollection<> properties private readonly MethodInfo removeMethod; ///"Contains" method support ICollection<> properties private readonly MethodInfo containsMethod; ///IsKeyProperty? private bool keyProperty; ///The other property in this type that holds the MIME type for this one private ClientProperty mimeTypeProperty; ////// constructor /// /// property /// propertyType /// keyProperty #if ASTORIA_OPEN_OBJECT /// openObjectProperty internal ClientProperty(PropertyInfo property, Type propertyType, bool keyProperty, bool openObjectProperty) #else internal ClientProperty(PropertyInfo property, Type propertyType, bool keyProperty) #endif { Debug.Assert(null != property, "null property"); Debug.Assert(null != propertyType, "null propertyType"); Debug.Assert(null == Nullable.GetUnderlyingType(propertyType), "should already have been denullified"); this.PropertyName = property.Name; this.NullablePropertyType = property.PropertyType; this.PropertyType = propertyType; this.propertyGetter = property.GetGetMethod(); this.propertySetter = property.GetSetMethod(); this.keyProperty = keyProperty; #if ASTORIA_OPEN_OBJECT this.OpenObjectProperty = openObjectProperty; #endif this.IsKnownType = ClientConvert.IsKnownType(propertyType); if (!this.IsKnownType) { this.setMethod = GetCollectionMethod(this.PropertyType, typeof(IDictionary<,>), "set_Item", out this.CollectionType); if (null == this.setMethod) { this.containsMethod = GetCollectionMethod(this.PropertyType, typeof(ICollection<>), "Contains", out this.CollectionType); this.addMethod = GetCollectionMethod(this.PropertyType, typeof(ICollection<>), "Add", out this.CollectionType); this.removeMethod = GetCollectionMethod(this.PropertyType, typeof(ICollection<>), "Remove", out this.CollectionType); } } Debug.Assert(!this.keyProperty || this.IsKnownType, "can't have an random type as key"); } ///what type was this property declared on? internal Type DeclaringType { get { return this.propertyGetter.DeclaringType; } } ///Does this property particpate in the primary key? internal bool KeyProperty { get { return this.keyProperty; } set { this.keyProperty = value; } } ///The other property in this type that holds the MIME type for this one internal ClientProperty MimeTypeProperty { get { return this.mimeTypeProperty; } set { this.mimeTypeProperty = value; } } ///get KeyProperty /// x ///KeyProperty internal static bool GetKeyProperty(ClientProperty x) { return x.KeyProperty; } ///get property name /// x ///PropertyName internal static string GetPropertyName(ClientProperty x) { return x.PropertyName; } ///compare name equality /// x /// y ///true if the property names are equal; false otherwise. internal static bool NameEquality(ClientProperty x, ClientProperty y) { return String.Equals(x.PropertyName, y.PropertyName); } ////// get property value from an object /// /// object to get the property value from ///property value internal object GetValue(object instance) { Debug.Assert(null != instance, "null instance"); Debug.Assert(null != this.propertyGetter, "null propertyGetter"); return this.propertyGetter.Invoke(instance, null); } ////// remove a item from collection /// /// collection /// item to remove internal void RemoveValue(object instance, object value) { Debug.Assert(null != instance, "null instance"); Debug.Assert(null != this.removeMethod, "missing removeMethod"); Debug.Assert(this.PropertyType.IsAssignableFrom(instance.GetType()), "unexpected collection instance"); Debug.Assert((null == value) || this.CollectionType.IsAssignableFrom(value.GetType()), "unexpected collection value to add"); this.removeMethod.Invoke(instance, new object[] { value }); } ////// set property value on an object /// /// object to set the property value on /// property value /// used for open type /// allow add to a collection if available, else allow setting collection property #if ASTORIA_OPEN_OBJECT /// cached OpenProperties dictionary internal void SetValue(object instance, object value, string propertyName, ref object openProperties, bool allowAdd) #else internal void SetValue(object instance, object value, string propertyName, bool allowAdd) #endif { Debug.Assert(null != instance, "null instance"); if (null != this.setMethod) { #if ASTORIA_OPEN_OBJECT if (this.OpenObjectProperty) { if (null == openProperties) { if (null == (openProperties = this.propertyGetter.Invoke(instance, null))) { throw Error.NotSupported(Strings.ClientType_NullOpenProperties(this.PropertyName)); } } ((IDictionary)openProperties)[propertyName] = value; } else #endif { Debug.Assert(this.PropertyType.IsAssignableFrom(instance.GetType()), "unexpected dictionary instance"); Debug.Assert((null == value) || this.CollectionType.IsAssignableFrom(value.GetType()), "unexpected dictionary value to set"); // ((IDictionary )instance)[propertyName] = (CollectionType)value; this.setMethod.Invoke(instance, new object[] { propertyName, value }); } } else if (allowAdd && (null != this.addMethod)) { Debug.Assert(this.PropertyType.IsAssignableFrom(instance.GetType()), "unexpected collection instance"); Debug.Assert((null == value) || this.CollectionType.IsAssignableFrom(value.GetType()), "unexpected collection value to add"); // ((ICollection )instance).Add((CollectionType)value); if (!(bool)this.containsMethod.Invoke(instance, new object[] { value })) { this.addMethod.Invoke(instance, new object[] { value }); } } else if (null != this.propertySetter) { Debug.Assert((null == value) || this.PropertyType.IsAssignableFrom(value.GetType()), "unexpected property value to set"); // ((ElementType)instance).PropertyName = (PropertyType)value; this.propertySetter.Invoke(instance, new object[] { value }); } else { throw Error.InvalidOperation(Strings.ClientType_MissingProperty(value.GetType().ToString(), propertyName)); } } } /// equality comparer for TypeName private sealed class TypeNameEqualityComparer : IEqualityComparer{ /// equality comparer for TypeName /// left type /// right type ///true if x and y are equal public bool Equals(TypeName x, TypeName y) { return (x.Type == y.Type && x.Name == y.Name); } ///compute hashcode for TypeName /// object to compute hashcode for ///computed hashcode public int GetHashCode(TypeName obj) { return obj.Type.GetHashCode() ^ obj.Name.GetHashCode(); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // //// type resolver // //--------------------------------------------------------------------- namespace System.Data.Services.Client { using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Data.Services.Common; using System.Linq; ////// wrapper around a clr type to /// get/set properties /// add items to collections /// support open types /// [DebuggerDisplay("{ElementTypeName}")] internal sealed class ClientType { ///what is the clr full name using ToString for generic name expansion internal readonly string ElementTypeName; ///what clr type does this represent internal readonly Type ElementType; ///if HasKeys then EntityType else if !KnownType then ComplexType else PrimitiveType internal readonly bool HasKeys; ///count of keys on entity type internal readonly int KeyCount; #region static fields ///appdomain cache discovered types with properties that we materialize private static readonly Dictionarytypes = new Dictionary (); /// cache <T> and wireName to mapped type private static readonly DictionarynamedTypes = new Dictionary (new TypeNameEqualityComparer()); #endregion #if ASTORIA_OPEN_OBJECT /// IDictionary<string,object> OpenProperites { get; } private readonly ClientProperty openProperties; #endif ///properties private ArraySetproperties; /// Property that holds data for ATOM-style media link entries private ClientProperty mediaDataMember; ////// discover and prepare properties for usage /// /// type being processed /// parameter name /// Whether the skip the check for settable properties. private ClientType(Type type, string typeName, bool skipSettableCheck) { Debug.Assert(null != type, "null type"); Debug.Assert(!String.IsNullOrEmpty(typeName), "empty typeName"); this.ElementTypeName = typeName; this.ElementType = Nullable.GetUnderlyingType(type) ?? type; #if ASTORIA_OPEN_OBJECT string openObjectPropertyName = null; #endif if (!ClientConvert.IsKnownType(this.ElementType)) { #if ASTORIA_OPEN_OBJECT #region OpenObject determined by walking type hierarchy and looking for [OpenObjectAttribute("PropertyName")] Type openObjectDeclared = this.ElementType; for (Type tmp = openObjectDeclared; (null != tmp) && (typeof(object) != tmp); tmp = tmp.BaseType) { object[] attributes = openObjectDeclared.GetCustomAttributes(typeof(OpenObjectAttribute), false); if (1 == attributes.Length) { if (null != openObjectPropertyName) { throw Error.InvalidOperation(Strings.Clienttype_MultipleOpenProperty(this.ElementTypeName)); } openObjectPropertyName = ((OpenObjectAttribute)attributes[0]).OpenObjectPropertyName; openObjectDeclared = tmp; } } #endregion #endif Type keyPropertyDeclaredType = null; DataServiceKeyAttribute dska = type.GetCustomAttributes(true).OfType().FirstOrDefault(); foreach (PropertyInfo pinfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { //// examples where class //// the normal examples //// PropertyType Property { get; set } //// Nullable Property { get; set; } //// if 'Property: struct' then we would be unable set the property during construction (and have them stick) //// but when its a class, we can navigate if non-null and set the nested properties //// PropertyType Property { get; } where PropertyType: class //// we do support adding elements to collections //// ICollection { get; /*ignored set;*/ } //// indexed properties are not suported because //// we don't have anything to use as the index //// PropertyType Property[object x] { /*ignored get;*/ /*ignored set;*/ } //// also ignored //// if PropertyType.IsPointer (like byte*) //// if PropertyType.IsArray except for byte[] and char[] //// if PropertyType == IntPtr or UIntPtr Type ptype = pinfo.PropertyType; // class / interface / value ptype = Nullable.GetUnderlyingType(ptype) ?? ptype; if (ptype.IsPointer || (ptype.IsArray && (typeof(byte[]) != ptype) && typeof(char[]) != ptype) || (typeof(IntPtr) == ptype) || (typeof(UIntPtr) == ptype)) { continue; } Debug.Assert(!ptype.ContainsGenericParameters, "remove when test case is found that encounters this"); if (pinfo.CanRead && (!ptype.IsValueType || pinfo.CanWrite) && !ptype.ContainsGenericParameters && (0 == pinfo.GetIndexParameters().Length)) { #region IsKey? bool keyProperty = dska != null ? dska.KeyNames.Contains(pinfo.Name) : false; if (keyProperty) { if (null == keyPropertyDeclaredType) { keyPropertyDeclaredType = pinfo.DeclaringType; } else if (keyPropertyDeclaredType != pinfo.DeclaringType) { throw Error.InvalidOperation(Strings.ClientType_KeysOnDifferentDeclaredType(this.ElementTypeName)); } if (!ClientConvert.IsKnownType(ptype)) { throw Error.InvalidOperation(Strings.ClientType_KeysMustBeSimpleTypes(this.ElementTypeName)); } this.KeyCount++; } #endregion #if ASTORIA_OPEN_OBJECT #region IsOpenObjectProperty? bool openProperty = (openObjectPropertyName == pinfo.Name) && typeof(IDictionary ).IsAssignableFrom(ptype); Debug.Assert(keyProperty != openProperty || (!keyProperty && !openProperty), "key can't be open type"); #endregion ClientProperty property = new ClientProperty(pinfo, ptype, keyProperty, openProperty); if (!property.OpenObjectProperty) #else ClientProperty property = new ClientProperty(pinfo, ptype, keyProperty); #endif { if (!this.properties.Add(property, ClientProperty.NameEquality)) { // 2nd property with same name shadows another property int shadow = this.IndexOfProperty(property.PropertyName); if (!property.DeclaringType.IsAssignableFrom(this.properties[shadow].DeclaringType)) { // the new property is on the most derived class this.properties.RemoveAt(shadow); this.properties.Add(property, null); } } } #if ASTORIA_OPEN_OBJECT else { if (pinfo.DeclaringType == openObjectDeclared) { this.openProperties = property; } } #endif } } #region No KeyAttribute, discover key by name pattern { DeclaringType.Name+ID, ID } if (null == keyPropertyDeclaredType) { ClientProperty key = null; for (int i = this.properties.Count - 1; 0 <= i; --i) { string propertyName = this.properties[i].PropertyName; if (propertyName.EndsWith("ID", StringComparison.Ordinal)) { string declaringTypeName = this.properties[i].DeclaringType.Name; if ((propertyName.Length == (declaringTypeName.Length + 2)) && propertyName.StartsWith(declaringTypeName, StringComparison.Ordinal)) { // matched "DeclaringType.Name+ID" pattern if ((null == keyPropertyDeclaredType) || this.properties[i].DeclaringType.IsAssignableFrom(keyPropertyDeclaredType)) { keyPropertyDeclaredType = this.properties[i].DeclaringType; key = this.properties[i]; } } else if ((null == keyPropertyDeclaredType) && (2 == propertyName.Length)) { // matched "ID" pattern keyPropertyDeclaredType = this.properties[i].DeclaringType; key = this.properties[i]; } } } if (null != key) { Debug.Assert(0 == this.KeyCount, "shouldn't have a key yet"); key.KeyProperty = true; this.KeyCount++; } } else if (this.KeyCount != dska.KeyNames.Count) { var m = (from string a in dska.KeyNames where null == (from b in this.properties where b.PropertyName == a select b).FirstOrDefault() select a).First (); throw Error.InvalidOperation(Strings.ClientType_MissingProperty(this.ElementTypeName, m)); } #endregion this.HasKeys = (null != keyPropertyDeclaredType); Debug.Assert(this.KeyCount == this.Properties.Where(k => k.KeyProperty).Count(), "KeyCount mismatch"); this.WireUpMimeTypeProperties(); this.CheckMediaLinkEntry(); if (!skipSettableCheck) { #if ASTORIA_OPEN_OBJECT if ((0 == this.properties.Count) && (null == this.openProperties)) #else if (0 == this.properties.Count) #endif { // implicit construction? throw Error.InvalidOperation(Strings.ClientType_NoSettableFields(this.ElementTypeName)); } } } this.properties.Sort (ClientProperty.GetPropertyName, String.CompareOrdinal); #if ASTORIA_OPEN_OBJECT #region Validate OpenObjectAttribute was used if ((null != openObjectPropertyName) && (null == this.openProperties)) { throw Error.InvalidOperation(Strings.ClientType_MissingOpenProperty(this.ElementTypeName, openObjectPropertyName)); } Debug.Assert((null != openObjectPropertyName) == (null != this.openProperties), "OpenProperties mismatch"); #endregion #endif } /// Properties sorted by name internal ArraySetProperties { get { return this.properties; } } /// Property that holds data for ATOM-style media link entries internal ClientProperty MediaDataMember { get { return this.mediaDataMember; } } ////// get a client type resolver /// /// type to wrap ///client type internal static ClientType Create(Type type) { return Create(type, true /* expectModelType */); } ////// get a client type resolver /// /// type to wrap /// Whether the type is expected to be a model type. ///client type internal static ClientType Create(Type type, bool expectModelType) { ClientType clientType; lock (ClientType.types) { ClientType.types.TryGetValue(type, out clientType); } if (null == clientType) { bool skipSettableCheck = !expectModelType; clientType = new ClientType(type, type.ToString(), skipSettableCheck); // ToString expands generic type name where as FullName does not if (expectModelType) { lock (ClientType.types) { ClientType existing; if (ClientType.types.TryGetValue(type, out existing)) { clientType = existing; } else { ClientType.types.Add(type, clientType); } } } } return clientType; } #if !ASTORIA_LIGHT ////// resolve the wireName/userType pair to a CLR type /// /// type name sent by server /// type passed by user or on propertyType from a class ///mapped clr type internal static Type ResolveFromName(string wireName, Type userType) #else ////// resolve the wireName/userType pair to a CLR type /// /// type name sent by server /// type passed by user or on propertyType from a class /// typeof context for strongly typed assembly ///mapped clr type internal static Type ResolveFromName(string wireName, Type userType, Type contextType) #endif { Type foundType; TypeName typename; typename.Type = userType; typename.Name = wireName; lock (ClientType.namedTypes) { ClientType.namedTypes.TryGetValue(typename, out foundType); } if (null == foundType) { string name = wireName; int index = wireName.LastIndexOf('.'); if ((0 <= index) && (index < wireName.Length - 1)) { name = wireName.Substring(index + 1); } if (userType.Name == name) { foundType = userType; } else { #if !ASTORIA_LIGHT // searching only loaded assemblies, not referenced assemblies foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) #else foreach (Assembly assembly in new Assembly[] { userType.Assembly, contextType.Assembly }.Distinct()) #endif { Type found = assembly.GetType(wireName, false); ResolveSubclass(name, userType, found, ref foundType); if (null == found) { Type[] types = null; try { types = assembly.GetTypes(); } catch (ReflectionTypeLoadException) { } if (null != types) { foreach (Type t in types) { ResolveSubclass(name, userType, t, ref foundType); } } } } } if (null != foundType) { lock (ClientType.namedTypes) { ClientType.namedTypes[typename] = foundType; } } } return foundType; } ////// get concrete type that implements the genericTypeDefinitation /// /// starting type /// the generic type definition to find ///concrete type that implementats the generic type internal static Type GetImplementationType(Type propertyType, Type genericTypeDefinition) { if (IsConstructedGeneric(propertyType, genericTypeDefinition)) { // propertyType is ICollectionreturn propertyType; } else { Type implementationType = null; foreach (Type interfaceType in propertyType.GetInterfaces()) { if (IsConstructedGeneric(interfaceType, genericTypeDefinition)) { if (null == implementationType) { // found implmentation of ICollection implementationType = interfaceType; } else { // ICollection and ICollection throw Error.NotSupported(Strings.ClientType_MultipleImplementationNotSupported); } } } return implementationType; } } /// /// get element type, resolves ICollection and Nullable /// /// starting type /// the generic type definition to find /// the method to search for /// the collection type if found ///element types internal static MethodInfo GetCollectionMethod(Type propertyType, Type genericTypeDefinition, string methodName, out Type type) { Debug.Assert(null != propertyType, "null propertyType"); Debug.Assert(null != genericTypeDefinition, "null genericTypeDefinition"); Debug.Assert(genericTypeDefinition.IsGenericTypeDefinition, "!IsGenericTypeDefinition"); type = null; Type implementationType = GetImplementationType(propertyType, genericTypeDefinition); if (null != implementationType) { Type[] genericArguments = implementationType.GetGenericArguments(); MethodInfo methodInfo = implementationType.GetMethod(methodName); Debug.Assert(null != methodInfo, "should have found the method"); #if DEBUG Debug.Assert(null != genericArguments, "null genericArguments"); ParameterInfo[] parameters = methodInfo.GetParameters(); if (0 < parameters.Length) { // following assert was disabled for Contains which returns bool // Debug.Assert(typeof(void) == methodInfo.ReturnParameter.ParameterType, "method doesn't return void"); Debug.Assert(genericArguments.Length == parameters.Length, "genericArguments don't match parameters"); for (int i = 0; i < genericArguments.Length; ++i) { Debug.Assert(genericArguments[i] == parameters[i].ParameterType, "parameter doesn't match generic argument"); } } #endif type = genericArguments[genericArguments.Length - 1]; return methodInfo; } return null; } ////// create object using default constructor /// ///instance of propertyType internal object CreateInstance() { return Activator.CreateInstance(this.ElementType); } ////// get property wrapper for a property name, might be method around open types for otherwise unknown properties /// /// property name /// are missing properties ignored ///property wrapper ///for unknown properties on closed types internal ClientProperty GetProperty(string propertyName, bool ignoreMissingProperties) { int index = this.IndexOfProperty(propertyName); if (0 <= index) { return this.properties[index]; } #if ASTORIA_OPEN_OBJECT else if (null != this.openProperties) { return this.openProperties; } #endif else if (!ignoreMissingProperties) { throw Error.InvalidOperation(Strings.ClientType_MissingProperty(this.ElementTypeName, propertyName)); } return null; } ////// Checks whether the specified /// Type to check. /// Generic type for checkin. ///is a /// closed constructed type of the generic type. /// true if ///is a constructed type of . The check is an immediate check; no inheritance rules are applied. private static bool IsConstructedGeneric(Type type, Type genericTypeDefinition) { Debug.Assert(type != null, "type != null"); Debug.Assert(!type.ContainsGenericParameters, "remove when test case is found that encounters this"); Debug.Assert(genericTypeDefinition != null, "genericTypeDefinition != null"); return type.IsGenericType && (type.GetGenericTypeDefinition() == genericTypeDefinition) && !type.ContainsGenericParameters; } ////// is the type a visible subclass with correct name /// /// type name from server /// the type from user for materialization or property type /// type being tested /// the previously discovered matching type ///if the mapping is ambiguous private static void ResolveSubclass(string wireClassName, Type userType, Type type, ref Type existing) { if ((null != type) && type.IsVisible && (wireClassName == type.Name) && userType.IsAssignableFrom(type)) { if (null != existing) { throw Error.InvalidOperation(Strings.Deserialize_Current(existing, type)); } existing = type; } } ///get the index of a property /// propertyName ///index else -1 private int IndexOfProperty(string propertyName) { return this.properties.IndexOf(propertyName, ClientProperty.GetPropertyName, String.Equals); } ////// Find properties with dynamic MIME type related properties and /// set the references from each ClientProperty to its related MIME type property /// private void WireUpMimeTypeProperties() { MimeTypePropertyAttribute attribute = (MimeTypePropertyAttribute)this.ElementType.GetCustomAttributes(typeof(MimeTypePropertyAttribute), true).SingleOrDefault(); if (null != attribute) { int dataIndex, mimeTypeIndex; if ((0 > (dataIndex = this.IndexOfProperty(attribute.DataPropertyName))) || (0 > (mimeTypeIndex = this.IndexOfProperty(attribute.MimeTypePropertyName)))) { throw Error.InvalidOperation(Strings.ClientType_MissingMimeTypeProperty(attribute.DataPropertyName, attribute.MimeTypePropertyName)); } Debug.Assert(0 <= dataIndex, "missing data property"); Debug.Assert(0 <= mimeTypeIndex, "missing mime type property"); this.Properties[dataIndex].MimeTypeProperty = this.Properties[mimeTypeIndex]; } } ////// Check if this type represents an ATOM-style media link entry and /// if so mark the ClientType as such /// private void CheckMediaLinkEntry() { object[] attributes = this.ElementType.GetCustomAttributes(typeof(MediaEntryAttribute), true); if (attributes != null && attributes.Length > 0) { Debug.Assert(attributes.Length == 1, "The AttributeUsage in the attribute definition should be presenting more than 1 per property"); int index = this.IndexOfProperty(((MediaEntryAttribute)attributes[0]).MediaMemberName); if (index < 0) { throw Error.InvalidOperation(Strings.ClientType_MissingMediaEntryProperty( ((MediaEntryAttribute)attributes[0]).MediaMemberName)); } this.mediaDataMember = this.properties[index]; } } ///type + wireName combination private struct TypeName { ///type internal Type Type; ///type name from server internal string Name; } ////// wrapper around property methods /// [DebuggerDisplay("{PropertyName}")] internal sealed class ClientProperty { ///property name for debugging internal readonly string PropertyName; ///type of the property internal readonly Type NullablePropertyType; ///type of the property internal readonly Type PropertyType; ///what is the nested collection element internal readonly Type CollectionType; ////// Is this a known primitive/reference type or an entity/complex/collection type? /// internal readonly bool IsKnownType; #if ASTORIA_OPEN_OBJECT ///IDictionary<string,object> OpenProperites { get; } internal readonly bool OpenObjectProperty; #endif ///property getter private readonly MethodInfo propertyGetter; ///property setter private readonly MethodInfo propertySetter; ///"set_Item" method supporting IDictionary properties private readonly MethodInfo setMethod; ///"Add" method supporting ICollection<> properties private readonly MethodInfo addMethod; ///"Remove" method supporting ICollection<> properties private readonly MethodInfo removeMethod; ///"Contains" method support ICollection<> properties private readonly MethodInfo containsMethod; ///IsKeyProperty? private bool keyProperty; ///The other property in this type that holds the MIME type for this one private ClientProperty mimeTypeProperty; ////// constructor /// /// property /// propertyType /// keyProperty #if ASTORIA_OPEN_OBJECT /// openObjectProperty internal ClientProperty(PropertyInfo property, Type propertyType, bool keyProperty, bool openObjectProperty) #else internal ClientProperty(PropertyInfo property, Type propertyType, bool keyProperty) #endif { Debug.Assert(null != property, "null property"); Debug.Assert(null != propertyType, "null propertyType"); Debug.Assert(null == Nullable.GetUnderlyingType(propertyType), "should already have been denullified"); this.PropertyName = property.Name; this.NullablePropertyType = property.PropertyType; this.PropertyType = propertyType; this.propertyGetter = property.GetGetMethod(); this.propertySetter = property.GetSetMethod(); this.keyProperty = keyProperty; #if ASTORIA_OPEN_OBJECT this.OpenObjectProperty = openObjectProperty; #endif this.IsKnownType = ClientConvert.IsKnownType(propertyType); if (!this.IsKnownType) { this.setMethod = GetCollectionMethod(this.PropertyType, typeof(IDictionary<,>), "set_Item", out this.CollectionType); if (null == this.setMethod) { this.containsMethod = GetCollectionMethod(this.PropertyType, typeof(ICollection<>), "Contains", out this.CollectionType); this.addMethod = GetCollectionMethod(this.PropertyType, typeof(ICollection<>), "Add", out this.CollectionType); this.removeMethod = GetCollectionMethod(this.PropertyType, typeof(ICollection<>), "Remove", out this.CollectionType); } } Debug.Assert(!this.keyProperty || this.IsKnownType, "can't have an random type as key"); } ///what type was this property declared on? internal Type DeclaringType { get { return this.propertyGetter.DeclaringType; } } ///Does this property particpate in the primary key? internal bool KeyProperty { get { return this.keyProperty; } set { this.keyProperty = value; } } ///The other property in this type that holds the MIME type for this one internal ClientProperty MimeTypeProperty { get { return this.mimeTypeProperty; } set { this.mimeTypeProperty = value; } } ///get KeyProperty /// x ///KeyProperty internal static bool GetKeyProperty(ClientProperty x) { return x.KeyProperty; } ///get property name /// x ///PropertyName internal static string GetPropertyName(ClientProperty x) { return x.PropertyName; } ///compare name equality /// x /// y ///true if the property names are equal; false otherwise. internal static bool NameEquality(ClientProperty x, ClientProperty y) { return String.Equals(x.PropertyName, y.PropertyName); } ////// get property value from an object /// /// object to get the property value from ///property value internal object GetValue(object instance) { Debug.Assert(null != instance, "null instance"); Debug.Assert(null != this.propertyGetter, "null propertyGetter"); return this.propertyGetter.Invoke(instance, null); } ////// remove a item from collection /// /// collection /// item to remove internal void RemoveValue(object instance, object value) { Debug.Assert(null != instance, "null instance"); Debug.Assert(null != this.removeMethod, "missing removeMethod"); Debug.Assert(this.PropertyType.IsAssignableFrom(instance.GetType()), "unexpected collection instance"); Debug.Assert((null == value) || this.CollectionType.IsAssignableFrom(value.GetType()), "unexpected collection value to add"); this.removeMethod.Invoke(instance, new object[] { value }); } ////// set property value on an object /// /// object to set the property value on /// property value /// used for open type /// allow add to a collection if available, else allow setting collection property #if ASTORIA_OPEN_OBJECT /// cached OpenProperties dictionary internal void SetValue(object instance, object value, string propertyName, ref object openProperties, bool allowAdd) #else internal void SetValue(object instance, object value, string propertyName, bool allowAdd) #endif { Debug.Assert(null != instance, "null instance"); if (null != this.setMethod) { #if ASTORIA_OPEN_OBJECT if (this.OpenObjectProperty) { if (null == openProperties) { if (null == (openProperties = this.propertyGetter.Invoke(instance, null))) { throw Error.NotSupported(Strings.ClientType_NullOpenProperties(this.PropertyName)); } } ((IDictionary)openProperties)[propertyName] = value; } else #endif { Debug.Assert(this.PropertyType.IsAssignableFrom(instance.GetType()), "unexpected dictionary instance"); Debug.Assert((null == value) || this.CollectionType.IsAssignableFrom(value.GetType()), "unexpected dictionary value to set"); // ((IDictionary )instance)[propertyName] = (CollectionType)value; this.setMethod.Invoke(instance, new object[] { propertyName, value }); } } else if (allowAdd && (null != this.addMethod)) { Debug.Assert(this.PropertyType.IsAssignableFrom(instance.GetType()), "unexpected collection instance"); Debug.Assert((null == value) || this.CollectionType.IsAssignableFrom(value.GetType()), "unexpected collection value to add"); // ((ICollection )instance).Add((CollectionType)value); if (!(bool)this.containsMethod.Invoke(instance, new object[] { value })) { this.addMethod.Invoke(instance, new object[] { value }); } } else if (null != this.propertySetter) { Debug.Assert((null == value) || this.PropertyType.IsAssignableFrom(value.GetType()), "unexpected property value to set"); // ((ElementType)instance).PropertyName = (PropertyType)value; this.propertySetter.Invoke(instance, new object[] { value }); } else { throw Error.InvalidOperation(Strings.ClientType_MissingProperty(value.GetType().ToString(), propertyName)); } } } /// equality comparer for TypeName private sealed class TypeNameEqualityComparer : IEqualityComparer{ /// equality comparer for TypeName /// left type /// right type ///true if x and y are equal public bool Equals(TypeName x, TypeName y) { return (x.Type == y.Type && x.Name == y.Name); } ///compute hashcode for TypeName /// object to compute hashcode for ///computed hashcode public int GetHashCode(TypeName obj) { return obj.Type.GetHashCode() ^ obj.Name.GetHashCode(); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SpotLight.cs
- TextBoxBase.cs
- Bitmap.cs
- OdbcException.cs
- GenericXmlSecurityToken.cs
- PtsHelper.cs
- Menu.cs
- GroupQuery.cs
- OpenTypeLayout.cs
- TypeDescriptor.cs
- InputProviderSite.cs
- DeviceSpecificChoice.cs
- FamilyTypefaceCollection.cs
- CodeTypeDeclarationCollection.cs
- SvcMapFileSerializer.cs
- DateTimeValueSerializerContext.cs
- ArgumentException.cs
- Model3DCollection.cs
- CompilerLocalReference.cs
- DBSqlParserTableCollection.cs
- HostingPreferredMapPath.cs
- HttpRawResponse.cs
- ArgumentNullException.cs
- CuspData.cs
- InteropTrackingRecord.cs
- XmlNavigatorFilter.cs
- FileSystemEventArgs.cs
- ComplexBindingPropertiesAttribute.cs
- WindowsClientElement.cs
- BitConverter.cs
- DataBindingHandlerAttribute.cs
- QueryComponents.cs
- UITypeEditor.cs
- XmlSerializationWriter.cs
- ByteStorage.cs
- IdentityReference.cs
- SoapExtensionReflector.cs
- ButtonStandardAdapter.cs
- DbConnectionOptions.cs
- ErrorFormatterPage.cs
- InputQueue.cs
- IProvider.cs
- SingletonConnectionReader.cs
- ToolboxItemFilterAttribute.cs
- GlobalizationAssembly.cs
- ToolboxItemCollection.cs
- SqlCommandSet.cs
- Roles.cs
- ReceiveDesigner.xaml.cs
- FileDialog_Vista.cs
- QuarticEase.cs
- OdbcEnvironmentHandle.cs
- mediaclock.cs
- CodeSnippetExpression.cs
- ExpressionVisitor.cs
- MediaCommands.cs
- XmlDocument.cs
- ByteAnimationUsingKeyFrames.cs
- ParallelTimeline.cs
- DataGridTablesFactory.cs
- __ComObject.cs
- AutomationElementCollection.cs
- TrayIconDesigner.cs
- ListViewPagedDataSource.cs
- ImmutableObjectAttribute.cs
- TemplateBindingExpressionConverter.cs
- AudienceUriMode.cs
- SetterBaseCollection.cs
- EditingCommands.cs
- MobileControlPersister.cs
- SqlInfoMessageEvent.cs
- ControlCodeDomSerializer.cs
- SQLDecimalStorage.cs
- BaseParser.cs
- figurelength.cs
- EntitySqlException.cs
- MultipartContentParser.cs
- ObjectAnimationUsingKeyFrames.cs
- WorkflowApplicationUnloadedException.cs
- XhtmlBasicLiteralTextAdapter.cs
- XPathDescendantIterator.cs
- ResourceDisplayNameAttribute.cs
- StyleHelper.cs
- HttpWebRequestElement.cs
- ListMarkerLine.cs
- returneventsaver.cs
- TreeNode.cs
- ControllableStoryboardAction.cs
- DataQuery.cs
- ShadowGlyph.cs
- Rect3D.cs
- PrinterUnitConvert.cs
- BinHexDecoder.cs
- XamlInterfaces.cs
- WorkflowMarkupSerializer.cs
- SafeMILHandle.cs
- metadatamappinghashervisitor.cs
- Marshal.cs
- CssStyleCollection.cs
- XmlSchemaGroup.cs