/// <summary> /// Intializes a new instance of the <see cref="GeneratedProperty"/> class (for overrides). /// </summary> /// <param name="engine">The code generation engine.</param> /// <param name="property">Inherited property to override.</param> /// <param name="implementation">Implementation strategy to use (may be null).</param> internal GeneratedProperty( CodeGenEngine engine, InheritedProperty property, IPropertyImplementation implementation) : base(engine) { // check parameters if (property == null) { throw new ArgumentNullException("property"); } mName = property.Name; mKind = PropertyKind.Override; mType = property.Type; mGetAccessorMethod = engine.AddOverride(property.GetAccessor); mSetAccessorMethod = engine.AddOverride(property.SetAccessor); mImplementation = implementation; if (mImplementation != null) { mImplementation.Declare(engine, this); } // do not allow changes to overridden properties // (signature must match the signature of the inherited property) Freeze(); }
/// <summary> /// Intializes a new instance of the <see cref="GeneratedProperty"/> class. /// </summary> /// <param name="engine">The code generation engine.</param> /// <param name="kind">Kind of property to generate.</param> /// <param name="type">Type of the property.</param> /// <param name="name">Name of the property (may be null).</param> /// <param name="implementation">Implementation strategy to use (may be null).</param> internal GeneratedProperty( CodeGenEngine engine, PropertyKind kind, Type type, string name, IPropertyImplementation implementation) : base(engine) { // check parameters if (type == null) { throw new ArgumentNullException("type"); } // ensure that the specified type is public and all nested types are public, too // => otherwise the dynamically created assembly is not able to access it CodeGenHelpers.CheckTypeIsTotallyPublic(type); mName = name; mKind = kind; mType = type; if (mName == null || mName.Trim().Length == 0) { mName = "X" + Guid.NewGuid().ToString("N"); } // declare the 'get' accessor method mGetAccessorMethod = engine.AddMethod(kind.ToMethodKind(), "get_" + name, type, Type.EmptyTypes, Visibility.Public); mGetAccessorMethod.AdditionalMethodAttributes = MethodAttributes.SpecialName | MethodAttributes.HideBySig; // declare the 'set' accessor method mSetAccessorMethod = engine.AddMethod(kind.ToMethodKind(), "set_" + name, typeof(void), new Type[] { type }, Visibility.Public); mSetAccessorMethod.AdditionalMethodAttributes = MethodAttributes.SpecialName | MethodAttributes.HideBySig; mImplementation = implementation; if (mImplementation != null) { mImplementation.Declare(engine, this); } }
/// <summary> /// Adds an override for the current property. /// </summary> /// <param name="implementation"> /// Implementation strategy to use (may be null to skip implementation and add it lateron using /// the <see cref="GeneratedProperty.PropertyBuilder"/> property). /// </param> /// <returns>The generated property.</returns> public GeneratedProperty Override(IPropertyImplementation implementation) { return(Engine.AddOverride(this, implementation)); }
/// <summary> /// Initializes a new instance of the <see cref="GeneratedProperty"/> class /// (associates a standard <see cref="System.Windows.PropertyMetadata"/> object with a default value with the dependency property). /// </summary> /// <param name="engine">The code generation engine.</param> /// <param name="name">Name of the property (may be null).</param> /// <param name="type">Type of the property.</param> /// <param name="isReadOnly"> /// true, if the dependency property is read-only; /// false, if it is read-write. /// </param> /// <param name="initializer">A method that provides code creating the default value of the dependency property (may be null to use the type's default value).</param> internal GeneratedDependencyProperty( CodeGenEngine engine, string name, Type type, bool isReadOnly, DependencyPropertyInitializer initializer = null) : base(engine) { mName = name; mIsReadOnly = isReadOnly; // add the dependency property if (mIsReadOnly) { mDependencyPropertyField = (IGeneratedFieldInternal)engine.AddStaticField <System.Windows.DependencyPropertyKey>( name + "Property", Visibility.Public, (msil, field) => { MethodInfo registerReadOnlyMethod = typeof(System.Windows.DependencyProperty).GetMethod( "RegisterReadOnly", BindingFlags.Static, null, new Type[] { typeof(string), typeof(Type), typeof(Type), typeof(System.Windows.PropertyMetadata) }, null); msil.Emit(OpCodes.Ldstr, mName); msil.Emit(OpCodes.Ldtoken, type); msil.Emit(OpCodes.Ldtoken, engine.TypeBuilder); // create PropertyMetadata object ConstructorInfo propertyMetadataConstructor = typeof(System.Windows.PropertyMetadata).GetConstructor(new Type[] { typeof(object) }); if (initializer != null) { initializer(msil, this); } else { CodeGenHelpers.EmitLoadDefaultValue(msil, type, true); } msil.Emit(OpCodes.Newobj, propertyMetadataConstructor); // call DependencyProperty.RegisterReadOnly() method msil.Emit(OpCodes.Call, registerReadOnlyMethod); }); } else { mDependencyPropertyField = (IGeneratedFieldInternal)engine.AddStaticField <System.Windows.DependencyProperty>( name + "Property", Visibility.Public, (msil, field) => { MethodInfo registerMethod = typeof(System.Windows.DependencyProperty).GetMethod( "Register", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string), typeof(Type), typeof(Type), typeof(System.Windows.PropertyMetadata) }, null); msil.Emit(OpCodes.Ldstr, mName); msil.Emit(OpCodes.Ldtoken, type); msil.Emit(OpCodes.Ldtoken, engine.TypeBuilder); // create PropertyMetadata object ConstructorInfo propertyMetadataConstructor = typeof(System.Windows.PropertyMetadata).GetConstructor(new Type[] { typeof(object) }); if (initializer != null) { initializer(msil, this); } else { CodeGenHelpers.EmitLoadDefaultValue(msil, type, true); } msil.Emit(OpCodes.Newobj, propertyMetadataConstructor); // call DependencyProperty.Register() method msil.Emit(OpCodes.Call, registerMethod); }); } // add the accessor property mImplementation = new PropertyImplementation_DependencyProperty(this); mAccessorProperty = engine.AddProperty( name, type, PropertyKind.Normal, mImplementation); mAccessorProperty.GetAccessor.Visibility = CodeGeneration.Visibility.Public; mAccessorProperty.SetAccessor.Visibility = CodeGeneration.Visibility.Internal; }