Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / xsp / System / Web / Util / FastPropertyAccessor.cs / 2 / FastPropertyAccessor.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- using System; using System.Reflection; using System.Reflection.Emit; using System.Threading; using System.Collections; using System.Security; using System.Security.Permissions; namespace System.Web.Util { /* * Property Accessor Generator class * * The purpose of this class is to generate some IL code on the fly that can efficiently * access properties (and fields) of objects. This is an alternative to using * very slow reflection. */ internal class FastPropertyAccessor { private static object s_lockObject = new object(); private static FastPropertyAccessor s_accessorGenerator; private static Hashtable s_accessorCache; private static MethodInfo _getPropertyMethod; private static MethodInfo _setPropertyMethod; private static Type[] _getPropertyParameterList = new Type[] { typeof(object) }; private static Type[] _setPropertyParameterList = new Type[] { typeof(object), typeof(object) }; private static Type[] _interfacesToImplement; private static int _uniqueId; // Used to generate unique type ID's. // Property getter/setter must be public for codegen to access it. // Static properties are ignored, since this class only works on instances of objects. // Need to use DeclaredOnly to avoid AmbiguousMatchException if a property with // a different return type is hidden. private const BindingFlags _declaredFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly; private ModuleBuilder _dynamicModule = null; static FastPropertyAccessor() { // Get the SetProperty method, and make sure it has // the correct signature. _getPropertyMethod = typeof(IWebPropertyAccessor).GetMethod("GetProperty"); _setPropertyMethod = typeof(IWebPropertyAccessor).GetMethod("SetProperty"); // This will be needed later, when building the dynamic class. _interfacesToImplement = new Type[1]; _interfacesToImplement[0] = typeof(IWebPropertyAccessor); } private static String GetUniqueCompilationName() { return Guid.NewGuid().ToString().Replace('-', '_'); } [ReflectionPermission(SecurityAction.Assert, Flags=ReflectionPermissionFlag.ReflectionEmit)] Type GetPropertyAccessorTypeWithAssert(Type type, string propertyName, PropertyInfo propInfo, FieldInfo fieldInfo) { // Create the dynamic assembly if needed. Type accessorType; MethodInfo getterMethodInfo = null; MethodInfo setterMethodInfo = null; Type propertyType; if (propInfo != null) { // It'a a property getterMethodInfo = propInfo.GetGetMethod(); setterMethodInfo = propInfo.GetSetMethod(); propertyType = propInfo.PropertyType; } else { // If not, it must be a field propertyType = fieldInfo.FieldType; } if (_dynamicModule == null) { lock (this) { if (_dynamicModule == null) { // Use a unique name for each assembly. String name = GetUniqueCompilationName(); AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "A_" + name; // Create a new assembly. AssemblyBuilder newAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run, null, //directory to persist assembly null, //evidence copied from caller null, //requiredPermissions null, //optionalPermissions null, //refusedPermissions true //isSynchronized ); // Create a single module in the assembly. _dynamicModule = newAssembly.DefineDynamicModule("M_" + name); } } } // Give the factory a unique name. String typeName = System.Web.UI.Util.MakeValidTypeNameFromString(type.Name) + "_" + propertyName + "_" + (_uniqueId++); TypeBuilder accessorTypeBuilder = _dynamicModule.DefineType("T_" + typeName, TypeAttributes.Public, typeof(object), _interfacesToImplement); // // Define the GetProperty method. It must be virtual to be an interface implementation. // MethodBuilder method = accessorTypeBuilder.DefineMethod("GetProperty", MethodAttributes.Public | MethodAttributes.Virtual, typeof(Object), _getPropertyParameterList); // Generate IL. The generated IL corresponds to: // "return ((TargetType) target).Blah;" ILGenerator il = method.GetILGenerator(); if (getterMethodInfo != null) { il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Castclass, type); // Generate the getter call based on whether it's a Property or Field if (propInfo != null) il.EmitCall(OpCodes.Callvirt, getterMethodInfo, null); else il.Emit(OpCodes.Ldfld, fieldInfo); il.Emit(OpCodes.Box, propertyType); il.Emit(OpCodes.Ret); // Specify that this method implements GetProperty from the inherited interface. accessorTypeBuilder.DefineMethodOverride(method, _getPropertyMethod); } else { // Generate IL. The generated IL corresponds to "throw new InvalidOperationException" ConstructorInfo cons = typeof(InvalidOperationException).GetConstructor(Type.EmptyTypes); il.Emit(OpCodes.Newobj, cons); il.Emit(OpCodes.Throw); } // // Define the SetProperty method. It must be virtual to be an interface implementation. // method = accessorTypeBuilder.DefineMethod("SetProperty", MethodAttributes.Public | MethodAttributes.Virtual, null, _setPropertyParameterList); il = method.GetILGenerator(); // Don't generate any code in the setter if it's a readonly property. // We still need to have an implementation of SetProperty, but it does nothing. if (fieldInfo != null || setterMethodInfo != null) { // Generate IL. The generated IL corresponds to: // "((TargetType) target).Blah = (PropType) val;" il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Castclass, type); il.Emit(OpCodes.Ldarg_2); if (propertyType.IsPrimitive) { // Primitive type: deal with boxing il.Emit(OpCodes.Unbox, propertyType); // Emit the proper instruction for the type if (propertyType == typeof(sbyte)) { il.Emit(OpCodes.Ldind_I1); } else if (propertyType == typeof(byte)) { il.Emit(OpCodes.Ldind_U1); } else if (propertyType == typeof(short)) { il.Emit(OpCodes.Ldind_I2); } else if (propertyType == typeof(ushort)) { il.Emit(OpCodes.Ldind_U2); } else if (propertyType == typeof(uint)) { il.Emit(OpCodes.Ldind_U4); } else if (propertyType == typeof(int)) { il.Emit(OpCodes.Ldind_I4); } else if (propertyType == typeof(long)) { il.Emit(OpCodes.Ldind_I8); } else if (propertyType == typeof(ulong)) { il.Emit(OpCodes.Ldind_I8); // Somehow, there is no Ldind_u8 } else if (propertyType == typeof(bool)) { il.Emit(OpCodes.Ldind_I1); } else if (propertyType == typeof(char)) { il.Emit(OpCodes.Ldind_U2); } else if (propertyType == typeof(decimal)) { il.Emit(OpCodes.Ldobj, propertyType); } else if (propertyType == typeof(float)) { il.Emit(OpCodes.Ldind_R4); } else if (propertyType == typeof(double)) { il.Emit(OpCodes.Ldind_R8); } else { il.Emit(OpCodes.Ldobj, propertyType); } } else if (propertyType.IsValueType) { // Value type: deal with boxing il.Emit(OpCodes.Unbox, propertyType); il.Emit(OpCodes.Ldobj, propertyType); } else { // No boxing involved: just generate a standard cast il.Emit(OpCodes.Castclass, propertyType); } // Generate the assignment based on whether it's a Property or Field if (propInfo != null) il.EmitCall(OpCodes.Callvirt, setterMethodInfo, null); else il.Emit(OpCodes.Stfld, fieldInfo); } il.Emit(OpCodes.Ret); // Specify that this method implements SetProperty from the inherited interface. accessorTypeBuilder.DefineMethodOverride(method, _setPropertyMethod); // Bake in the type. accessorType = accessorTypeBuilder.CreateType(); return accessorType; } private static void GetPropertyInfo(Type type, string propertyName, out PropertyInfo propInfo, out FieldInfo fieldInfo, out Type declaringType) { // First, try to find a property with that name. Type.GetProperty() without BindingFlags.Declared // will throw AmbiguousMatchException if there is a hidden property with the same name and a // different type (VSWhidbey 237437). This method finds the property with the specified name // on the most specific type. propInfo = GetPropertyMostSpecific(type, propertyName); fieldInfo = null; if (propInfo != null) { // Get the most base Type where the property is first declared MethodInfo baseCheckMethodInfo = propInfo.GetGetMethod(); if (baseCheckMethodInfo == null) { baseCheckMethodInfo = propInfo.GetSetMethod(); } declaringType = baseCheckMethodInfo.GetBaseDefinition().DeclaringType; // DevDiv Bug 27734 // Ignore the declaring type if it's generic if (declaringType.IsGenericType) declaringType = type; // If they're different, get a new PropertyInfo if (declaringType != type) { // We want the propertyInfo for the property specifically declared on the declaringType. // So pass in the correct BindingFlags to avoid an AmbiguousMatchException, which would // be thrown if the declaringType hides a property with the same name and a different type. // VSWhidbey 518034 propInfo = declaringType.GetProperty(propertyName, _declaredFlags); } } else { // We couldn't find a property, so try a field // Type.GetField can not throw AmbiguousMatchException like Type.GetProperty above. fieldInfo = type.GetField(propertyName); // If we couldn't find a field either, give up if (fieldInfo == null) throw new ArgumentException(); declaringType = fieldInfo.DeclaringType; } } private static IWebPropertyAccessor GetPropertyAccessor(Type type, string propertyName) { if (s_accessorGenerator == null || s_accessorCache == null) { lock (s_lockObject) { if (s_accessorGenerator == null || s_accessorCache == null) { s_accessorGenerator = new FastPropertyAccessor(); s_accessorCache = new Hashtable(); } } } // First, check if we have it cached // Get a hash key based on the Type and the property name int cacheKey = HashCodeCombiner.CombineHashCodes( type.GetHashCode(), propertyName.GetHashCode()); IWebPropertyAccessor accessor = (IWebPropertyAccessor) s_accessorCache[cacheKey]; // It was cached, so just return it if (accessor != null) return accessor; FieldInfo fieldInfo = null; PropertyInfo propInfo = null; Type declaringType; GetPropertyInfo(type, propertyName, out propInfo, out fieldInfo, out declaringType); // If the Type where the property/field is declared is not the same as the current // Type, check if the declaring Type already has a cached accessor. This limits // the number of different accessors we need to create. e.g. Every control has // an ID property, but we'll end up only create one accessor for all of them. int declaringTypeCacheKey = 0; if (declaringType != type) { // Get a hash key based on the declaring Type and the property name declaringTypeCacheKey = HashCodeCombiner.CombineHashCodes( declaringType.GetHashCode(), propertyName.GetHashCode()); accessor = (IWebPropertyAccessor) s_accessorCache[declaringTypeCacheKey]; // We have a cached accessor for the declaring type, so use it if (accessor != null) { // Cache the declaring type's accessor as ourselves lock (s_accessorCache.SyncRoot) { s_accessorCache[cacheKey] = accessor; } return accessor; } } if (accessor == null) { Type propertyAccessorType; lock (s_accessorGenerator) { propertyAccessorType = s_accessorGenerator.GetPropertyAccessorTypeWithAssert( declaringType, propertyName, propInfo, fieldInfo); } // Create the type. This is the only place where Activator.CreateInstance is used, // reducing the calls to it from 1 per instance to 1 per type. accessor = (IWebPropertyAccessor) HttpRuntime.CreateNonPublicInstance(propertyAccessorType); } // Cache the accessor lock (s_accessorCache.SyncRoot) { s_accessorCache[cacheKey] = accessor; if (declaringTypeCacheKey != 0) s_accessorCache[declaringTypeCacheKey] = accessor; } return accessor; } internal static object GetProperty(object target, string propName, bool inDesigner) { if (!inDesigner) { IWebPropertyAccessor accessor = GetPropertyAccessor(target.GetType(), propName); return accessor.GetProperty(target); } else { // Dev10 bug 491386 - avoid CLR code path that causes an exception when designer uses two // assemblies of the same name at different locations FieldInfo fieldInfo = null; PropertyInfo propInfo = null; Type declaringType; GetPropertyInfo(target.GetType(), propName, out propInfo, out fieldInfo, out declaringType); if (propInfo != null) { return propInfo.GetValue(target, null); } else if (fieldInfo != null) { return fieldInfo.GetValue(target); } throw new ArgumentException(); } } // Finds the property with the specified name on the most specific type. private static PropertyInfo GetPropertyMostSpecific(Type type, string name) { PropertyInfo propInfo; Type currentType = type; while (currentType != null) { propInfo = currentType.GetProperty(name, _declaredFlags); if (propInfo != null) { return propInfo; } else { currentType = currentType.BaseType; } } return null; } internal static void SetProperty(object target, string propName, object val, bool inDesigner) { if (!inDesigner) { IWebPropertyAccessor accessor = GetPropertyAccessor(target.GetType(), propName); accessor.SetProperty(target, val); } else { // Dev10 bug 491386 - avoid CLR code path that causes an exception when designer uses two // assemblies of the same name at different locations FieldInfo fieldInfo = null; PropertyInfo propInfo = null; Type declaringType = null; GetPropertyInfo(target.GetType(), propName, out propInfo, out fieldInfo, out declaringType); if (propInfo != null) { propInfo.SetValue(target, val, null); } else if (fieldInfo != null) { fieldInfo.SetValue(target, val); } else { throw new ArgumentException(); } } } } [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] public interface IWebPropertyAccessor { object GetProperty(object target); void SetProperty(object target, object value); } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- using System; using System.Reflection; using System.Reflection.Emit; using System.Threading; using System.Collections; using System.Security; using System.Security.Permissions; namespace System.Web.Util { /* * Property Accessor Generator class * * The purpose of this class is to generate some IL code on the fly that can efficiently * access properties (and fields) of objects. This is an alternative to using * very slow reflection. */ internal class FastPropertyAccessor { private static object s_lockObject = new object(); private static FastPropertyAccessor s_accessorGenerator; private static Hashtable s_accessorCache; private static MethodInfo _getPropertyMethod; private static MethodInfo _setPropertyMethod; private static Type[] _getPropertyParameterList = new Type[] { typeof(object) }; private static Type[] _setPropertyParameterList = new Type[] { typeof(object), typeof(object) }; private static Type[] _interfacesToImplement; private static int _uniqueId; // Used to generate unique type ID's. // Property getter/setter must be public for codegen to access it. // Static properties are ignored, since this class only works on instances of objects. // Need to use DeclaredOnly to avoid AmbiguousMatchException if a property with // a different return type is hidden. private const BindingFlags _declaredFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly; private ModuleBuilder _dynamicModule = null; static FastPropertyAccessor() { // Get the SetProperty method, and make sure it has // the correct signature. _getPropertyMethod = typeof(IWebPropertyAccessor).GetMethod("GetProperty"); _setPropertyMethod = typeof(IWebPropertyAccessor).GetMethod("SetProperty"); // This will be needed later, when building the dynamic class. _interfacesToImplement = new Type[1]; _interfacesToImplement[0] = typeof(IWebPropertyAccessor); } private static String GetUniqueCompilationName() { return Guid.NewGuid().ToString().Replace('-', '_'); } [ReflectionPermission(SecurityAction.Assert, Flags=ReflectionPermissionFlag.ReflectionEmit)] Type GetPropertyAccessorTypeWithAssert(Type type, string propertyName, PropertyInfo propInfo, FieldInfo fieldInfo) { // Create the dynamic assembly if needed. Type accessorType; MethodInfo getterMethodInfo = null; MethodInfo setterMethodInfo = null; Type propertyType; if (propInfo != null) { // It'a a property getterMethodInfo = propInfo.GetGetMethod(); setterMethodInfo = propInfo.GetSetMethod(); propertyType = propInfo.PropertyType; } else { // If not, it must be a field propertyType = fieldInfo.FieldType; } if (_dynamicModule == null) { lock (this) { if (_dynamicModule == null) { // Use a unique name for each assembly. String name = GetUniqueCompilationName(); AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "A_" + name; // Create a new assembly. AssemblyBuilder newAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run, null, //directory to persist assembly null, //evidence copied from caller null, //requiredPermissions null, //optionalPermissions null, //refusedPermissions true //isSynchronized ); // Create a single module in the assembly. _dynamicModule = newAssembly.DefineDynamicModule("M_" + name); } } } // Give the factory a unique name. String typeName = System.Web.UI.Util.MakeValidTypeNameFromString(type.Name) + "_" + propertyName + "_" + (_uniqueId++); TypeBuilder accessorTypeBuilder = _dynamicModule.DefineType("T_" + typeName, TypeAttributes.Public, typeof(object), _interfacesToImplement); // // Define the GetProperty method. It must be virtual to be an interface implementation. // MethodBuilder method = accessorTypeBuilder.DefineMethod("GetProperty", MethodAttributes.Public | MethodAttributes.Virtual, typeof(Object), _getPropertyParameterList); // Generate IL. The generated IL corresponds to: // "return ((TargetType) target).Blah;" ILGenerator il = method.GetILGenerator(); if (getterMethodInfo != null) { il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Castclass, type); // Generate the getter call based on whether it's a Property or Field if (propInfo != null) il.EmitCall(OpCodes.Callvirt, getterMethodInfo, null); else il.Emit(OpCodes.Ldfld, fieldInfo); il.Emit(OpCodes.Box, propertyType); il.Emit(OpCodes.Ret); // Specify that this method implements GetProperty from the inherited interface. accessorTypeBuilder.DefineMethodOverride(method, _getPropertyMethod); } else { // Generate IL. The generated IL corresponds to "throw new InvalidOperationException" ConstructorInfo cons = typeof(InvalidOperationException).GetConstructor(Type.EmptyTypes); il.Emit(OpCodes.Newobj, cons); il.Emit(OpCodes.Throw); } // // Define the SetProperty method. It must be virtual to be an interface implementation. // method = accessorTypeBuilder.DefineMethod("SetProperty", MethodAttributes.Public | MethodAttributes.Virtual, null, _setPropertyParameterList); il = method.GetILGenerator(); // Don't generate any code in the setter if it's a readonly property. // We still need to have an implementation of SetProperty, but it does nothing. if (fieldInfo != null || setterMethodInfo != null) { // Generate IL. The generated IL corresponds to: // "((TargetType) target).Blah = (PropType) val;" il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Castclass, type); il.Emit(OpCodes.Ldarg_2); if (propertyType.IsPrimitive) { // Primitive type: deal with boxing il.Emit(OpCodes.Unbox, propertyType); // Emit the proper instruction for the type if (propertyType == typeof(sbyte)) { il.Emit(OpCodes.Ldind_I1); } else if (propertyType == typeof(byte)) { il.Emit(OpCodes.Ldind_U1); } else if (propertyType == typeof(short)) { il.Emit(OpCodes.Ldind_I2); } else if (propertyType == typeof(ushort)) { il.Emit(OpCodes.Ldind_U2); } else if (propertyType == typeof(uint)) { il.Emit(OpCodes.Ldind_U4); } else if (propertyType == typeof(int)) { il.Emit(OpCodes.Ldind_I4); } else if (propertyType == typeof(long)) { il.Emit(OpCodes.Ldind_I8); } else if (propertyType == typeof(ulong)) { il.Emit(OpCodes.Ldind_I8); // Somehow, there is no Ldind_u8 } else if (propertyType == typeof(bool)) { il.Emit(OpCodes.Ldind_I1); } else if (propertyType == typeof(char)) { il.Emit(OpCodes.Ldind_U2); } else if (propertyType == typeof(decimal)) { il.Emit(OpCodes.Ldobj, propertyType); } else if (propertyType == typeof(float)) { il.Emit(OpCodes.Ldind_R4); } else if (propertyType == typeof(double)) { il.Emit(OpCodes.Ldind_R8); } else { il.Emit(OpCodes.Ldobj, propertyType); } } else if (propertyType.IsValueType) { // Value type: deal with boxing il.Emit(OpCodes.Unbox, propertyType); il.Emit(OpCodes.Ldobj, propertyType); } else { // No boxing involved: just generate a standard cast il.Emit(OpCodes.Castclass, propertyType); } // Generate the assignment based on whether it's a Property or Field if (propInfo != null) il.EmitCall(OpCodes.Callvirt, setterMethodInfo, null); else il.Emit(OpCodes.Stfld, fieldInfo); } il.Emit(OpCodes.Ret); // Specify that this method implements SetProperty from the inherited interface. accessorTypeBuilder.DefineMethodOverride(method, _setPropertyMethod); // Bake in the type. accessorType = accessorTypeBuilder.CreateType(); return accessorType; } private static void GetPropertyInfo(Type type, string propertyName, out PropertyInfo propInfo, out FieldInfo fieldInfo, out Type declaringType) { // First, try to find a property with that name. Type.GetProperty() without BindingFlags.Declared // will throw AmbiguousMatchException if there is a hidden property with the same name and a // different type (VSWhidbey 237437). This method finds the property with the specified name // on the most specific type. propInfo = GetPropertyMostSpecific(type, propertyName); fieldInfo = null; if (propInfo != null) { // Get the most base Type where the property is first declared MethodInfo baseCheckMethodInfo = propInfo.GetGetMethod(); if (baseCheckMethodInfo == null) { baseCheckMethodInfo = propInfo.GetSetMethod(); } declaringType = baseCheckMethodInfo.GetBaseDefinition().DeclaringType; // DevDiv Bug 27734 // Ignore the declaring type if it's generic if (declaringType.IsGenericType) declaringType = type; // If they're different, get a new PropertyInfo if (declaringType != type) { // We want the propertyInfo for the property specifically declared on the declaringType. // So pass in the correct BindingFlags to avoid an AmbiguousMatchException, which would // be thrown if the declaringType hides a property with the same name and a different type. // VSWhidbey 518034 propInfo = declaringType.GetProperty(propertyName, _declaredFlags); } } else { // We couldn't find a property, so try a field // Type.GetField can not throw AmbiguousMatchException like Type.GetProperty above. fieldInfo = type.GetField(propertyName); // If we couldn't find a field either, give up if (fieldInfo == null) throw new ArgumentException(); declaringType = fieldInfo.DeclaringType; } } private static IWebPropertyAccessor GetPropertyAccessor(Type type, string propertyName) { if (s_accessorGenerator == null || s_accessorCache == null) { lock (s_lockObject) { if (s_accessorGenerator == null || s_accessorCache == null) { s_accessorGenerator = new FastPropertyAccessor(); s_accessorCache = new Hashtable(); } } } // First, check if we have it cached // Get a hash key based on the Type and the property name int cacheKey = HashCodeCombiner.CombineHashCodes( type.GetHashCode(), propertyName.GetHashCode()); IWebPropertyAccessor accessor = (IWebPropertyAccessor) s_accessorCache[cacheKey]; // It was cached, so just return it if (accessor != null) return accessor; FieldInfo fieldInfo = null; PropertyInfo propInfo = null; Type declaringType; GetPropertyInfo(type, propertyName, out propInfo, out fieldInfo, out declaringType); // If the Type where the property/field is declared is not the same as the current // Type, check if the declaring Type already has a cached accessor. This limits // the number of different accessors we need to create. e.g. Every control has // an ID property, but we'll end up only create one accessor for all of them. int declaringTypeCacheKey = 0; if (declaringType != type) { // Get a hash key based on the declaring Type and the property name declaringTypeCacheKey = HashCodeCombiner.CombineHashCodes( declaringType.GetHashCode(), propertyName.GetHashCode()); accessor = (IWebPropertyAccessor) s_accessorCache[declaringTypeCacheKey]; // We have a cached accessor for the declaring type, so use it if (accessor != null) { // Cache the declaring type's accessor as ourselves lock (s_accessorCache.SyncRoot) { s_accessorCache[cacheKey] = accessor; } return accessor; } } if (accessor == null) { Type propertyAccessorType; lock (s_accessorGenerator) { propertyAccessorType = s_accessorGenerator.GetPropertyAccessorTypeWithAssert( declaringType, propertyName, propInfo, fieldInfo); } // Create the type. This is the only place where Activator.CreateInstance is used, // reducing the calls to it from 1 per instance to 1 per type. accessor = (IWebPropertyAccessor) HttpRuntime.CreateNonPublicInstance(propertyAccessorType); } // Cache the accessor lock (s_accessorCache.SyncRoot) { s_accessorCache[cacheKey] = accessor; if (declaringTypeCacheKey != 0) s_accessorCache[declaringTypeCacheKey] = accessor; } return accessor; } internal static object GetProperty(object target, string propName, bool inDesigner) { if (!inDesigner) { IWebPropertyAccessor accessor = GetPropertyAccessor(target.GetType(), propName); return accessor.GetProperty(target); } else { // Dev10 bug 491386 - avoid CLR code path that causes an exception when designer uses two // assemblies of the same name at different locations FieldInfo fieldInfo = null; PropertyInfo propInfo = null; Type declaringType; GetPropertyInfo(target.GetType(), propName, out propInfo, out fieldInfo, out declaringType); if (propInfo != null) { return propInfo.GetValue(target, null); } else if (fieldInfo != null) { return fieldInfo.GetValue(target); } throw new ArgumentException(); } } // Finds the property with the specified name on the most specific type. private static PropertyInfo GetPropertyMostSpecific(Type type, string name) { PropertyInfo propInfo; Type currentType = type; while (currentType != null) { propInfo = currentType.GetProperty(name, _declaredFlags); if (propInfo != null) { return propInfo; } else { currentType = currentType.BaseType; } } return null; } internal static void SetProperty(object target, string propName, object val, bool inDesigner) { if (!inDesigner) { IWebPropertyAccessor accessor = GetPropertyAccessor(target.GetType(), propName); accessor.SetProperty(target, val); } else { // Dev10 bug 491386 - avoid CLR code path that causes an exception when designer uses two // assemblies of the same name at different locations FieldInfo fieldInfo = null; PropertyInfo propInfo = null; Type declaringType = null; GetPropertyInfo(target.GetType(), propName, out propInfo, out fieldInfo, out declaringType); if (propInfo != null) { propInfo.SetValue(target, val, null); } else if (fieldInfo != null) { fieldInfo.SetValue(target, val); } else { throw new ArgumentException(); } } } } [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] public interface IWebPropertyAccessor { object GetProperty(object target); void SetProperty(object target, object value); } } // 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
- RotateTransform3D.cs
- PaperSize.cs
- UrlAuthorizationModule.cs
- DataObjectCopyingEventArgs.cs
- ProfessionalColorTable.cs
- DataGridHeadersVisibilityToVisibilityConverter.cs
- PriorityChain.cs
- ServicePointManager.cs
- Setter.cs
- Context.cs
- HttpServerUtilityBase.cs
- DataGridViewCellLinkedList.cs
- WebPartConnectionCollection.cs
- SettingsPropertyValueCollection.cs
- WebAdminConfigurationHelper.cs
- ColorPalette.cs
- RuntimeWrappedException.cs
- JsonWriter.cs
- CodeCommentStatement.cs
- AnnotationHelper.cs
- CodeAttributeDeclaration.cs
- TextEmbeddedObject.cs
- DelayLoadType.cs
- UriSchemeKeyedCollection.cs
- SafeNativeMethods.cs
- ClientRolePrincipal.cs
- Exceptions.cs
- Unit.cs
- _ListenerResponseStream.cs
- TabRenderer.cs
- AudioLevelUpdatedEventArgs.cs
- SymbolPair.cs
- BrowserDefinitionCollection.cs
- GeneralTransform3DGroup.cs
- Condition.cs
- CodeGen.cs
- EventHandlerList.cs
- PocoPropertyAccessorStrategy.cs
- ListView.cs
- TraceContext.cs
- StylusPointProperty.cs
- InternalConfigSettingsFactory.cs
- WebControlParameterProxy.cs
- ExpressionConverter.cs
- SqlInternalConnection.cs
- DefaultBinder.cs
- InstanceKey.cs
- VerificationAttribute.cs
- VisualBasicSettingsHandler.cs
- PropertyValueUIItem.cs
- Triplet.cs
- EntityDataSourceContainerNameItem.cs
- BmpBitmapEncoder.cs
- XmlHierarchyData.cs
- CodeIndexerExpression.cs
- SessionStateUtil.cs
- ExpandableObjectConverter.cs
- Logging.cs
- StateWorkerRequest.cs
- ResizeBehavior.cs
- HtmlObjectListAdapter.cs
- UserCancellationException.cs
- _TLSstream.cs
- SqlFlattener.cs
- DBSchemaRow.cs
- EventProvider.cs
- TraceContext.cs
- BaseDataList.cs
- ErrorWrapper.cs
- StoragePropertyMapping.cs
- NextPreviousPagerField.cs
- DataAccessor.cs
- XmlHelper.cs
- ProfileModule.cs
- Menu.cs
- DataControlPagerLinkButton.cs
- NavigationWindow.cs
- WinEventHandler.cs
- DBCSCodePageEncoding.cs
- DoubleCollectionValueSerializer.cs
- DispatcherHookEventArgs.cs
- PropagatorResult.cs
- PeerApplication.cs
- HostedTransportConfigurationBase.cs
- FixedSOMLineRanges.cs
- PieceDirectory.cs
- StringAttributeCollection.cs
- DataSvcMapFileSerializer.cs
- FormattedTextSymbols.cs
- DragCompletedEventArgs.cs
- IncrementalReadDecoders.cs
- SectionXmlInfo.cs
- RichTextBox.cs
- ToolStripArrowRenderEventArgs.cs
- FileLevelControlBuilderAttribute.cs
- MatchingStyle.cs
- DbSource.cs
- EncoderNLS.cs
- CommonObjectSecurity.cs
- ResourcesBuildProvider.cs