/// <summary> /// Register Property /// </summary> /// <typeparam name="T">Type of Target</typeparam> /// <typeparam name="P">Type of property</typeparam> /// <param name="propertyLambdaExpression">Property Expression</param> /// <param name="defaultValue">Default Value for the property</param> /// <returns></returns> protected static ManagedProperty <P> RegisterProperty <T, P>(Expression <Func <T, object> > propertyLambdaExpression, P defaultValue) { var reflectedPropertyInfo = Reflect <T> .GetProperty(propertyLambdaExpression); var property = new ManagedProperty <P>( typeof(T), reflectedPropertyInfo.Name, new ManagedPropertyMetadata <P>() { DefaultValue = defaultValue }); ManagedPropertyRepository.Instance.RegisterProperty(property); return(property); }
/// <summary> /// 注册某个属性到容器中 /// /// 线程安全。 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="property"></param> /// <returns></returns> public ManagedProperty <T> RegisterProperty <T>(ManagedProperty <T> property) { if (property == null) { throw new ArgumentNullException("property"); } if (property.GlobalIndex >= 0) { throw new InvalidOperationException("同一个属性只能注册一次。"); } var ownerType = property.OwnerType; /*********************** 代码块解释 ********************************* * * 属性注册的顺序是: * * 启动时,需要先注册所有的编译期扩展属性。 * * 注册该类型自身定义的所有编译期正常属性。 * * 运行时注册的运行期动态属性。 * * 所以: * 1. 如果不是注册扩展属性,需要保证该类型的静态构造函数首先被执行。 * 2. 如果不是注册扩展属性,并且声明的类型并不是属性的拥有者,则可以理解该属性为运行期动态属性。 * **********************************************************************/ property.LifeCycle = ManagedPropertyLifeCycle.Compile; if (this._isExtensionRegistered) { RunPropertyResigtry(ownerType); if (ownerType != property.DeclareType) { property.LifeCycle = ManagedPropertyLifeCycle.Runtime; } } else { if (!this._isRegisteringExtension) { throw new InvalidProgramException("在注册所有扩展属性前,不能使用 RegisterProperty 方法注册任何其它属性。(请查看代码是否在托管属性初始化完成之前,就已经开始使用托管属性了。)"); } } //找到或创建 TypePropertiesContainer lock (_statusLock) { property.GlobalIndex = _nextGlobalIndex++; } var typeProperties = this.GetOrCreateTypeProperties(ownerType); lock (typeProperties.Lock) { //生命周期从编译变化到 Runtime 时,需要调用 CompleteCompileProperties if (typeProperties.CurLifeCycle == ManagedPropertyLifeCycle.Compile && property.LifeCycle == ManagedPropertyLifeCycle.Runtime) { CompleteCompileProperties(typeProperties); } //以下代码把托管属性加入到容器对应的集合中。 if (typeProperties.CurLifeCycle == ManagedPropertyLifeCycle.Compile) { typeProperties.AddCompiledProperty(property, this._sortAsAdding); if (!this._sortAsAdding) { if (_changedList == null) { _changedList = new List <TypePropertiesContainer>(5000); } _changedList.Add(typeProperties); } } else { if (property.LifeCycle == ManagedPropertyLifeCycle.Compile) { throw new InvalidProgramException(string.Format( @"类型 {0} 的托管属性已经进入运行期,不能再注册编译期属性:{1}。 可能的原因:在 {0} 类型以外的类型中注册了 {1} 属性。" , property.OwnerType, property.Name)); } typeProperties.AddRuntimeProperty(property); } } property.DefaultMeta.Freeze(); return(property); }
/// <summary> /// 设置某个 bool 类型托管属性的值。 /// </summary> /// <param name="property"></param> /// <param name="value"></param> /// <param name="source">本次值设置的来源。</param> /// <returns>返回最终使用的值。</returns> public object SetProperty(ManagedProperty <bool> property, bool value, ManagedPropertyChangedSource source = ManagedPropertyChangedSource.FromProperty) { //使用 BooleanBoxes 来防止装箱操作。 return(this._SetProperty(property, BooleanBoxes.Box(value), source)); }
/// <summary> /// 获取某个托管属性的值。 /// </summary> /// <typeparam name="TPropertyType"></typeparam> /// <param name="property"></param> /// <returns></returns> public TPropertyType GetProperty <TPropertyType>(ManagedProperty <TPropertyType> property) { //属性拆箱 return((TPropertyType)this._GetProperty(property)); }
internal void SetProperty(ManagedProperty <TPropertyType> property) { this._property = property; }