2014网站设计域名注册后怎么使用

news/2025/9/23 7:29:53/文章来源:
2014网站设计,域名注册后怎么使用,湘潭有实力seo优化,物联网平台开源这篇设计文档是 12 月份写来参加公司的研发峰会的#xff0c;自己倒是信心满满#xff0c;不过最后还是没有入围。现在想想也没啥大用#xff0c;所以贴出来#xff0c;期待与园友交流。 文档有点长#xff0c;没全部贴在博客中#xff0c;有兴趣的可以下载附件中的 PDF。…    这篇设计文档是 12 月份写来参加公司的研发峰会的自己倒是信心满满不过最后还是没有入围。现在想想也没啥大用所以贴出来期待与园友交流。     文档有点长没全部贴在博客中有兴趣的可以下载附件中的 PDF。  附件《实体扩展属性系统-系统设计说明书.pdf》 分隔线     目录 前言... 4 1 背景与需求... 5 1.1 产品 721 客户化开发的需要... 5 1.2 实体动态列... 6 1.3 分离只读/视图属性... 6 1.4 提升框架性能... 6 1.5 支持 WPF 绑定... 6 1.6 其它需求... 7 2 分析... 8 2.1 主要功能需求... 8 2.2 非功能需求分析... 8 2.3 约束... 9 2.4 风险... 9 3 设计方案... 10 3.1 一些决策... 10 3.2 风险点验证... 10 3.2.1 支持 WPF 绑定... 10 3.2.2 性能关键点... 12 3.3 方案描述... 12 3.3.1 结构说明... 13 3.3.2 相关UML图... 14 3.3.3 如何支撑需求... 18 3.4 重点实现细节... 18 4 设计验证... 24 4.1 功能需求验证... 24 4.2 WPF绑定验证... 24 4.3 性能验证... 25 5 使用手册... 25 5.1 使用场景介绍单元测试... 25 5.1.1 属性默认值... 26 5.1.2 强制替换属性值... 27 5.1.3 属性值设置时的取消与强制替换... 27 5.1.4 引用实体属性的设置取消... 28 5.1.5 属性变更事件... 29 5.1.6 产品721扩展属性... 30 5.1.7 所有扩展属性的界面生成... 31 5.1.8 只读属性的使用方法... 31 5.1.9 只读扩展属性的使用方法... 32 5.1.10 运行时动态属性动态列... 33 5.1.11 序列化... 34 5.1.12 WPF绑定验证... 35 5.1.13 扩展属性ORM验证... 35 5.1.14 实体状态的相关属性... 35 5.2 代码生成 – CodeSnippets. 36 5.3 其它问题... 37 5.3.1 扩展属性的CLR属性编写注意点... 37 5.3.2 何时使用属性扩展何时使用继承扩展... 38 前言 在产品线开发中支持产品的客户化在产品规模化开发中是非常重要的一部分。而客户化中的非常重要的一部分则是属性值的客户化包括属性值的添加、删除、修改及属性对应的界面的客户化。由于产品对属性值的扩展方案一直是使用类继承的方案来完成导致了产品出现了许多的问题 l 其中最重要一个问题是有时候无法给一个客户两个可选的的功能包而为了解决这个问题开发人员又不得不做大量的代码移植把可选包的代码都移植到主干版本中导致了临时代码过多维护成本太大。 l 另外我们的产品基于实体开发为实现动态列的需求绕了许多路最终决定使用数据表的模式来编写同样造成大量重复代码开发人员开发效率低下。 基于历史遗留的这些问题我们设计了全新的属性系统。本系统设计完成之后解决了许多历史遗留问题也带来了许多意想不到的价值。例如 l 支持简单地完成客户化开发中属性的扩展。 l 支持更简单地实现领域实体的动态属性界面中的动态列原来要100行代码现在只要20行。 l 视图属性分离更好的可维护性 l 属性性能提升性能提升 l 减少了序列化数据传输效率提升性能提升 l 统一的属性接口平台可提供更加强大的功能支持 本次设计是在历史代码上进行重构但是本质上是设计一个完全独立功能的子系统。本文从需求、分析、方案、实现、验证等角度说明了整个设计是如何完成的。并在最后给出了系统的使用手册以帮助开发人员日常应用。 备注 本文档中为了方便起见将会把“实体扩展属性系统”简称为 EMPS。Entity Managed Property System意为实体托管属性系统 另外文中说到的版本号历史的OEA版本是2.5升级到EMPS之后OEA版本是2.6。 1 背景与需求 本节主要说明整个系统设计之初设计的背景及最终整理出来的需求列表。这些需求是前期不断收集、累积的结果。接下来将会详细说明一些主要的需求 1.1 产品 721 客户化开发的需要 部门的几个产品都是基于 OEA 平台开发的。OEA 平台主要解决产品开发模式下客户化开发、以及在产品开发过程中如何提高开发效率两大问题。 关于产品开发中的721概念及OEA中的客户化设计参见《基于OEA框架的客户化设计三 “插件式”DLL》。关于 OEA 的了解参见《OEA 框架演示 - 快过原型的产品开发》。 客户化开发中主要解决的问题是如何在客户化版本中对主干版本中的产品进行扩展。各种扩展一般都依托于底层的元数据这些元数据描述整个系统。当我们对元数据进行修改时整个应用程序也就发生了相应的变化。这些产品的扩展可以简单分为模块级别的扩展、实体级别的扩展、属性级别的扩展。模块的扩展在此不进行讨论。 先说属性扩展我们一般会对产品中定义好的类的属性进行以下扩展添加一个属性、删除一个属性、修改一个属性。所以扩展并不只是意味着添加。添加属性意味着我们需要为已经定义完成的类添加一个额外的属性这个属性可以映射到数据库可以在产品界面中显示行为和直接定义的属性是一致的。删除属性则意味着数据库中不再有对应的字段界面不再显示。修改属性一般只会修改属性的各种元数据例如修改它映射数据库的字段元数据修改它在界面中显示的列的元数据等这些修改其实已经在元数据的设计方案中解决相关内容可以查看《基于OEA框架的客户化设计一 总体设计》、《基于OEA框架的客户化设计二 元数据设计》以及《基于OEA框架的客户化设计三 “插件式”DLL》。 实体的扩展一般可以通过继承的方法实现当继承出新的子类后在元数据中用它将原来的父类进行覆盖即可。有些时候我们还会为某个类扩展一些聚合父子关系例如我们可以为某一个建设项目扩展出其相关的合同列表这样原来只显示项目的界面中就能紧接着显示每一个项目相应的合同列表。而这种聚合父子关系的扩展虽然是实体级别的添加但是实质上是对实体添加新的一对多关系。也就是说这种实体的扩展可以转换为属性扩展即在原有实体的基础上扩展一个一对多关系的属性。 基于以上分析我们知道一个可扩展的属性系统几乎是客户化软件产品运行时的最基础设施。 在 2.6 版本之前的 OEA属性扩展主要使用继承的方式来实现。简单地说就是继承需要扩展的实体添加新的属性然后使用这个实体替换掉原来的类。该方案主要是为了实现属性的添加但是属性的删除以及修改都是通过修改属性的元描述来实现的。这样的方式导致了许多问题属性的删除只是删除了界面而数据库、运行时实体也都还存在该属性属性的修改不能修改属性中的行为代码重点说下属性的添加造成的缺点 经常需要对某个类扩展一两个属性而现在只能继承出子类同时把父类隐藏起来或者直接覆盖父类用进来比较复杂; 同时类型变多开发人员的学习成本维护成本都随之变大。 更重要的是.NET 中 CLR 单继承体系的限制使得通过继承无法实现这样的扩展: 两个独立的扩展包“2”以可选的形式对主包“7”进行扩展也就是说产品 721 客户化开发中两个“2”的扩展包是两个单独的程序集但是单继承的限制我们不能同时使用它们。对于这种情况我们目前的处理方式是把两个“2”的包都放到了主包中而使用元数据的方式对不需要的功能来进行隐藏这种实现方式是临时的、错误的。 1.2 实体动态列 软件开发中常常遇到动态列的需求表格中的数据的列是根据数据本身自动生成的这对于基于领域实体类型、基于非动态类型的技术框架来开发的系统来说要实现动态列基本上不可能。所以往往应用程序会另辟捷径使用 DataTable 来重新组装数据后再显示。这导致两种模式同时存在于一个系统中同样的代码会重复出现增加维护成本。界面的代码不一致也加大了界面自动生成的困难。 如果有了扩展属性我们则可以在任意实体上扩展各种新的属性界面也就相应地成了“动态”列。 1.3 分离只读/视图属性 实体设计中常常会添加一些只读的属性它的值是使用实体当前的值经过计算后得出。在 OEA 中实体被设计为分布式对象简单地说就是客户端和服务端重用一套实体代码。可以参见CSLA框架设计书籍《Expert C# 2008 Business Objects》。这些分布式对象被直接绑定到界面上。为了界面显示的需要常常会为它们添加许多只读的视图属性这样就导致了视图属性过多混杂在领域实体的代码中污染了代码加大维护难度。 如果有了扩展属性我们则可以把这个只读属性都放到一个单独的类中去为这个实体做扩展这样就可以得到更简洁、结构更清晰的代码。 1.4 提升框架性能 对于框架开发来说常常需要在框架中对实体的属性做统一的处理来向应用层提供强大的功能支持。如果使用一般的实体设计那么属性值的获取、设置都不可避免地要使用到反射。而大量的属性值操作将会意味着较差的性能。如果有了托管属性则在框架层面能够使用和应用一致的属性 API 来操作属性不再使用反射速度可以有不少提升。 1.5 支持 WPF 绑定 一般情况下我们使用 WPF 绑定时都是直接绑定到 CLR 托管属性上。但是如果使用扩展属性的话并不是所有属性都会有一个 CLR 属性封装器。所以这些扩展属性必须支持 WPF 绑定也是我们的需求之一。 1.6 其它需求 l 支持属性反扩展 在产品 721 开发中常常在 “1” 的客户化版本中需要删除 “2”版本中为“7”扩展的属性这时需要支持属性的反扩展或叫反注册。 l 获取属性值来源 由于目前 OEA 框架中的实体是分布式对象我们常常需要在实体属性改变时分辨属性值的来源是数据库还是UI界面还是来自程序中的其它代码。 l 定制序列化的数据 实体属性被框架管理后可以很轻易地实现各种数据格式的序列化。 l 需要支持属性值的验证、强制、更改通知等事件通知。 l 元数据重载 属性的一切行为都将以回调的形式存放在元数据中。而元数据是可以被重载的。这样子类就才重写这些行为。同时我们就可以在进行产品客户化的时候为属性重新定制这些行为。 最后可以看一下在《实体扩展属性方案分析脑图》脑图文档中整理出来的需求概况图这些需求都是历史版本中所不能支持的 图1. 实体扩展属性需求列表 2 分析 由于前面已经把需求整理得比较明朗了。那么这里我们首先要分析出主要需求、约束及相关的风险等。关于框架设计的整个过程可以参考这篇文章《框架模块设计经验总结》。 2.1 主要功能需求 其实在图一中已经把需求按照优先级别进行了划分后面的整个设计将会围绕这些需求进行。其中最主要的功能性需求是以下三个。而设计目标则是至少实现以下三个需求其它需求则按优先级尽可能实现。 l 721客户化开发中的属性扩展 l 属性托管受框架管理意思是需要为上层框架提供统一维护属性值的功能。 l 动态列 2.2 非功能需求分析 l 运行时性能 实体属性可以说是实体设计中最重要的部分。而它的性能好坏则关系到系统中每一个实体的每一个属性这些属性都直接关系到应用的性能。简单地说如果属性系统慢上层应用的性能必然会慢。换句话说属性系统的代码开发是对性能十分敏感的在核心代码上需要十分谨慎。 2.5 版本的OEA框架使用的属性主要还是 .NET 中的原生 CLR属性系统 CSLA 开源框架中的属性系统。主要是为了支持属性的统一管理。而本次设计可以对系统带来许多的新功能和支持加之原有系统的属性性能并没有构成应用层开发的性能问题所以一定的性能消耗是可以接受的。 对这项的要求是 使用同样的代码和历史属性系统进行属性测试对比耗时不能超过原有的120%。 比较简单也比较严格。一旦不满足此项整个设计不可以被使用。 l 独立性 虽然实体扩展属性系统是作为 OEA 框架的一个重要组成部分但是托管属性、扩展属性的需求在开发过程中常常会碰到。所以我们需要把实体扩展属性系统设计为一个独立的 DLL这样它就可以在非 OEA平台的环境中使用。 l 可扩展性 EMPS的可扩展性并不是指该系统带来的属性的可扩展性这其实是EMPS的功能需求而是指属性系统本身需要进行一些扩展。 当前OEA框架中以产品元数据为整个框架的基础设施。也就是说OEA 框架中有管理应用中所有元数据的功能。而由图1中的需求列表可以看到EMPS也需要元数据的支持例如属性的默认值。但是独立性中已经要求EMPS被设计为一个完全独立的模块也就是说EMPS完全不依赖 OEA。那么这些属性的元数据如何支持使用 OEA 来进行保存呢这同样是EMPS 设计过程中需要特殊考虑的一个扩展点。 l 易用性 此项为框架设计必须考虑的一个非功能需求。 2.3 约束 l ORM功能的修改 原来的OEA的ORM中支持使用OEAORM及EntityFramework4.1CodeFirst两种模式但是这两种ORM当前无疑都只支持对CLR属性的映射。而扩展属性是没有CLR属性包装器的但是这些扩展属性同样需要映射数据库。 也就是说如果EMPS开发完成要映射新的扩展属性必须要修改当前OEAORM模块。同时无法再支持EntityFramework4.1了EFCodeFirst基于CLR属性来进行映射。 l 原有属性功能的兼容 2.5 版本的OEA使用的属性主要还是 .NET 中的原生 CLR属性系统 CSLA 开源框架中的属性系统。这些属性中已经写了非常多的代码。属性的 Get 获取器及 Set 设置器中的代码可谓五花八门。这些都必须在新的属性系统中被完全兼容否则必须导致业务功能出现问题。 l 大量历史代码的修改 由于本次设计本质上是一次在历史版本上的重构而产品开发截止到目前已经产生了几万行的历史代码其中的实体属性也是几千个。重构如此底层的设计在尽量保证应用层 API 不变的前提下也必然会造成较多的修改同时很可能会引起比较多的BUG。这是一个必须考虑的约束条件。 2.4 风险 l 属性性能 由非功能需求的描述中知道性能是至关重要的。关系到整个设计是否可用。但是最终开发出来的模块性能在设计时很难测量的。对于这个风险的规避使用以下方案分析历史属性系统的关键性能影响点在设计稿完成后理论上检查这些关键点是否能在新设计出来的属性系统下运行良好。 l 支持WPF绑定 这是一个技术难关。 当前我们只是使用了 WPF 中直接绑定CLR属性的方案。如何能让我们在客户化版本的程序集中扩展的扩展属性也支持WPF绑定成为了一个技术上的难题。 对这点的规避很简单在整个设计开始之前先分析WPF绑定中的内部机制解决这个问题后才能开始其它的设计。 3 设计方案 3.1 一些决策 由于本系统的设计比较复杂。所以先对兼容性约束做了一个决策 在设计过程中尽量考虑功能上与原属性系统保持兼容接口上保持一致。但是当无法兼容或者无法保持一致的接口时可以不兼容。但是这些不兼容的设计点都需要记录下来当设计完成后逐个修改。如果改动较大则使用组内的重构工具完成。 3.2 风险点验证 3.2.1 支持 WPF 绑定 经过查阅MSDN及搜索出的网络资源发现WPF中的绑定机制支持绑定DataTable数据表类型而表中的字段则是动态的根据结果数据的变化而变化。所以只要搞清楚DataTable是如何被WPF绑定支持的那么EMPS也可以使用同样的机制进行绑定。 以下是WPF中DataTable的绑定机制分析 图2. WPF中DataTable支持绑定的核心类型分析 图3. WPF中为DataTable生成视图模型的流程图 重点在于DataTable 实现 IListSource接口并构造动态的视图动态类型 DataRowView并使其实现ICustomTypeDescriptor。详细过程参见这篇文章《OEA 扩展属性系统 - 任意适配 WPF Binding 的设计分析》以及本系列中的文档《任意适配 WPF Binding 的设计分析》。 搞清楚了整个设计及创建流程那么其实在设计EMPS时支持这个机制就可以了。 3.2.2 性能关键点 需要分析历史框架中的属性系统CSLA托管属性系统在做到托管属性的同时是如何保证性能的呢 其实它其中属性的核心重点在于使用强类型的FieldDataT来存储每一个属性并使用定长的属性值的数组来存放 private IFieldData[] _fieldData; 这样的好处在于强类型保证了没有装箱拆箱操作同时定长的数组支持了以O(1)的复杂度来查找指定属性 但是这样搜索属性的前提是属性值数组定长而一个实体类型到底有多少个属性是在编译期已经完全确定下来的。换句话说在这个数组初始化时必须知道固定的属性个数这违背了属性可扩展的需求这也是为什么使用这个属性系统很难做到扩展的原因。 当然在对其进行较大改动的前提下也不是不可能。但是考虑到CSLA是个开源框架其满足需求与我们的需求有较大的区别代码比较臃肿也无法实现我们所需要的一些功能对它做大型的改动不如重新做一个完全符合需求的托管属性框架。 经过之前的分析可以想到要得到较高性能的托管属性系统最好也是使用“强类型存储属性值”加“定长数组”的方案。但是如何支持属性的扩展呢“划分属性定义期”是个较好的解决方案。之后的主体设计中会对这个方案进行详细的描述。 3.3 方案描述 整个设计中借鉴了CSLA托管属性以及WPF依赖属性的设计然后再构建出我们自己的属性系统 3.3.1 结构说明 图4. EMPS结构说明 脑图比较简单其中的具体内容可以参考脑图《扩展属性方案》。这里只做简要说明 l 静态结构 总体上静态结构比较简单主要分为两个层次。底层是抽象的属性元数据提供子系统而另一层则是依赖于前者而构建的EMPS核心运行时扩展属性子系统。 提取抽象的属性元数据提供系统是为了使元数据的存储、提供都抽象化后面可以和 OEA 中的元数据存储模块进行适配。 而核心的EMPS则实现了整个的托管属性。后面将会对其以类图的形式重点说明。 l 动态结构 在这里比较特殊地提出了属性生命周期的概念。属性的生命周期规定了属性被定义或者被反注册的时期可能叫定义期会比较正确。这里主要有编译期、启动期、运行期。 l 编译期 此阶段中定义的属性主要包括使用代码编写的一般属性、扩展属性。当然也包括“2”和“1”的扩展包中编写的一些对“7”的包中实体类进行扩展的扩展属性。 定义属性时一同指定它对应的元数据。 l 启动期 此阶段主要以客户化定义的方式来对编译期属性及其相应的元数据进行修改。 l 运行期 该阶段主要用于附加运行时动态属性。 这些动态属性一般只用于显示它们会影响界面的生成。属性的扩展和删除要在生成控件之前就能确定否则界面没有对应的列。 由于影响界面生成所以需要为其指定OEA框架中对应的界面元数据。如果不指定则使用默认元数据。不过这些元数据的设计会在OEA框架中完成与EMPS的设计无关。 在这个阶段中扩展的附加属性不会与服务端程序有任何关系。也就是说不需要为这些扩展属性定义 ORM 等服务端元数据。当然了这些属性的数据也不需要序列化后在网络上进行传输。 划分出这几个周期的主要原因使得可以判断出某个实体的编译期、启动期属性列表长度。这是因为编译期和启动期已经定义、修改或者客户化的属性当程序进入运行时后是不会再发生改变的。而这些属性占据了应用开发的95%以上。所以我们只要知道了编译期启动期属性的长度也就意味着可以使用O(1)检索的数组来存放而不是更慢的List/HashTable保证了这些属性的性能。而对于运行时属性来说虽然它的长度不能固定根据业务场景而变化但是使用情况较少可以不考虑性能。 3.3.2 相关UML图 完整的UML图参见《实体扩展属性UML设计图》。下面将挑选重点进行说明。 图5.扩展属性核心类结构概要设计图 这张是实现扩展属性的核心类结构概要设计图其中主要包含 ManagedPropertyObject、ManagedProperty、ManagedPropertyField、ManagedPropertyMeta等。由于是概要设计图其中的方法、属性等相对实现完成后的系统来比肯定不完整但是它的作用主要是说明整个设计的核心思想。其中 ManagedProperty 表示托管属性每定义一个托管属性系统都会生成一个此类型的对象用于标记。获取、设置属性的值时都需要提供此标记来进行检索。 ManagedPropertyMeta 表示托管属性元数据其中提供了许多信息例如默认值、是否只读、属性变更逻辑回调等这些元数据对属性值的获取、设置的逻辑都有着比较大的影响。 ManagedPropertyField 表示某个对象中某个托管属性对应的值。其实这个类后期在实现时会被定义为泛型类这样值的存储就不是object而是强类型的不需要装箱拆箱操作。 ManagedPropertyObject 表示拥有托管属性的对象基类实体其中定义了根据ManagedProperty来获取、设置值的接口这使得该对象能够象一般对象一样获取、存储各种值。同时它也提供了统一处理所有托管属性值的接口此类统一处理的接口在应用开发时很少用到主要给上层的框架使用。上层框架可以应用这些接口完成以下的框架任务统一的对象值拷贝、统一的序列化、检索特定类型的值等这样的值的获取、设置速度远比反射要快。 图6. 扩展属性仓储概要设计图 这张图说明整个系统中的托管属性都是被系统中的单例对象 ManagedPropertyRepository 给管理起来的为了给上层提供更方便的查询功能也方便存储它使用 TypeIndicators 类来存储某个实体类型的属性列表。TypeIndicators这个类也负责为上层提供查询某一个类型已经定义好的属性列表、某一类型及其所有父类定义的所有属性的联合属性列表。同时这个类中的属性都会生成在类型中的属性的索引这样在获取属性值时就可以使用这个索引在属性值数组中进行属性值的查找。 图7.扩展属性元数据概要设计图 前面提到过为了保证 EMPS的独立性我们需要把托管属性元数据的数据获取方案抽象化这里的 IPropertyMetaProvider 就是抽象的元数据提供器接口。而上层的OEA框架则会实现自己的提供器 OEAPropertyMetaProvider并通过自己的元数据模块中的信息例如图中的OEAPropertyMeta来为托管属性提供元数据。 图8. 扩展属性实体实现WPF绑定相关概要设计图 这张图看上去会比较眼熟没错它和图2中的WPF支持DataTable绑定的类图比较相似。主要也是让 EntityList 实现 IListSource接口并添加 EntityView 类实现 ICustomTypeDescriptor 接口这样就可以实现动态属性的WPF绑定了。 3.3.3 如何支撑需求 主要的设计方案及类图看完之后我们需要考虑整个方案是否能支撑起前面说到的所有需求。下图是对整个需求的可支撑性进行分析。相关内容可以参见《实体扩展属性方案分析脑图》,在此不再赘述。 图9. 设计方案对需求的支持度分析。 3.4 重点实现细节 在对需求支持分析之后再经过召开的设计评审会议发现这样的方案可以实现基本全部需求。这样就进入实现环节了。实现环节就关注更多了细节性设计。本文档将会挑选一部分重点进行说明。 首先先来看看最终完成的代码中最核心部分的代码结构图 图10. 核心代码结构图 整个结构的实现与设计相差无几。接下来说明一些相对重要的代码 l 先是ManagedPropertyObject中的属性值获取、设置相关代码 前面的设计方案中提到这个类主要作为所有实体类的基类提供值的获取、设置等。而这个类其实是把属性值的管理都放到了内部的一个类ManagedPropertyObjectFieldsManager 中 并把相关的操作都代理到这个类上 而 ManagedPropertyObjectFieldsManager则实现了这些逻辑的核心代码。其中它的私有字段定义如下 可以看到编译期、启动期属性值与运行期属性值被分开存放。前者使用数组构造函数直接初始化而后者则在需要时才会被序列化。还注意到它继承自CustomSerializationObject使得整个属性值列表是可以被自定义序列化的。下面是泛型的属性值获取与设置逻辑 internal TPropertyType GetPropertyTPropertyType(ManagedPropertyTPropertyType property) { var useDefault true;     TPropertyType result default(TPropertyType); if (property.IsReadOnly)     {         result (property as ManagedPropertyTPropertyType).ProvideReadOnlyValue(this._owner);         useDefault false;     } else     { if (property.LifeCycle ManagedPropertyLifeCycle.CompileOrSetup)         { var field this._compiledFields[property.TypeCompiledIndex] as ManagedPropertyFieldTPropertyType; if (field ! null)             {                 result field.Value;                 useDefault false;             }         } else         { if (this._runtimeFields ! null)             { IManagedPropertyField f; if (this._runtimeFields.TryGetValue(property, out f))                 { var field f as ManagedPropertyFieldTPropertyType;                     result field.Value;                     useDefault false;                 }             }         } } var meta property.GetMeta(this); if (useDefault) result meta.DefaultValue; result meta.CoerceGetValue(this._owner, result); return result; } internal void SetPropertyTPropertyType(ManagedPropertyTPropertyType property, TPropertyType value, ManagedPropertyChangedSource source) {     ForceNotReadOnly(property); var meta property.GetMeta(this); bool cancel meta.RaisePropertyChanging(this._owner, ref value, source); if (cancel) return; var hasOldValue false;     TPropertyType oldValue default(TPropertyType); ManagedPropertyFieldTPropertyType field null; //这个 if 块中的代码查找或创建对应 property 的 field同时记录可能存在的历史值。 if (property.LifeCycle ManagedPropertyLifeCycle.CompileOrSetup)     {         field this._compiledFields[property.TypeCompiledIndex] as ManagedPropertyFieldTPropertyType; if (field null)         { //不管是不是默认值都进行存储。 //不需要检测默认值更加快速但是浪费了一些小的空间。 //默认值的检测在 GetNonDefaultPropertyValues 方法中进行实现。             field property.CreateField(); this._compiledFields[property.TypeCompiledIndex] field;         } else         {             oldValue field.Value;             hasOldValue true;         }     } else     { if (this._runtimeFields null)         { this._runtimeFields new DictionaryIManagedProperty, IManagedPropertyField();         } else         { IManagedPropertyField f; if (this._runtimeFields.TryGetValue(property, out f))             {                 field f as ManagedPropertyFieldTPropertyType;                 oldValue field.Value;                 hasOldValue true;             }         } if (field null)         {             field property.CreateField(); this._runtimeFields.Add(property, field);         }     }     field.Value value; if (!hasOldValue) { oldValue meta.DefaultValue; } if (!object.Equals(oldValue, value))     { //发生 Meta 中的事件 var args meta.RaisePropertyChanged( this._owner, oldValue, value, source             ); //发生事件 this._owner.RaisePropertyChanged(args);     } } 可以看到编译期属性主要通过一维数组进行存放数组中每一个元素都是强类型的泛型对象 ManagedPropertyFieldTPropertyType。 另外要注意的是该类提供了同样的非泛型接口 非泛型方法主要是为上次框架提供其中主要考虑装箱拆箱操作的性能消耗。关于接口加泛型类的底层框架设计方案参见《重构实践体验interface的威力(一)》、《重构实践体验interface的威力(二)》。 GetProperty、SetProperty 方法是对性能最敏感的两个方法其实现必须特别小心其内部调用的每一个方法如 ManagedProperty.GetMeta(ManagedPropertyObject owner)、ManagedPropertyMetadata.RaisePropertyChanged等也都必须要做特别的优化需要考虑到装箱拆箱、属性检索、不构造多余对象等。具体代码设计参考实际工程中的代码在此不做过多描述。 l 注册属性及反注册属性的方法位于 ManagedPropertyRepository类中。 其主要的职责是构造ManagedProperty对象并计算它的一些重要属性例如用于属性快速Hash的GlobalIndex、用于编译期属性检索值时使用的数组下标TypeIndex等。 4 设计验证 4.1 功能需求验证 已经为EMPS添加了丰富的单元测试该项验证的内容被整合到第5项中参见《5.使用手册》。 4.2 WPF绑定验证 验证这个比较简单只要基于它的应用程序运行起来之后界面上的值都能正常获取、设置即可。 不过我们还是为它加了相应的单元测试这个在后面会有描述。 4.3 性能验证 之前说到如果EMPS相比原来的属性系统如果耗时超过120%则该系统不可用。按照之前关键性能点的设计应该是可以达到但是还是需要做出相应的验证工作及最终的数据。 具体内容可以参见《实体扩展属性系统性能测试报告》。这里说明一下最终结论 “ 性能结论 新的 OEA 托管属性系统在带来众多新功能的同时不但没有降低原有性能反而因为优化掉无用的代码使得速度提升。故可以放心使用该属性系统。 ” 5 使用手册 5.1 使用场景介绍单元测试 由于已经为EMPS添加了比较丰富的单元测试所以本使用手册将主要以介绍单元测试的形式覆盖所有可能的使用场景并介绍每一个场景其对应的使用方法。 单元测试所使用的实体类包含下图中的这些类 右图是所涉及到的所有单元测试。 “……………………内容较多省略有兴趣的可以看附件中的文档………………” 5.2 代码生成 – CodeSnippets 在《OEA 框架演示 - 快过原型的产品开发》中可以看到OEA框架的快速开发能力中编译期的代码生成技术是一个重要部分。我们同样为EMPS的80%使用场景都编写了CodeSnippets关于CodeSnippets的使用方法参见《善用VS中的Code Snippet来提高开发效率》 导入VS后只要输入OEAP……VS就支持这些代码片段的生成如 5.3 其它问题 5.3.1 扩展属性的CLR属性编写注意点 使用EMPS定义的属性如果不是扩展属性都会定义一个对应的CLR属性包装器如 注意CLR属性内不能添加任何代码所有需要对Code属性的Get、Set的定制代码都需要以回调的形式编写在EMPS中如 原因是界面框架、ORM框架、WPF绑定等框架内容都不会调用CLR属性而是直接调用GetProperty、SetProperty方法而CLR中的代码只是为了方便类库的使用。 5.3.2 何时使用属性扩展何时使用继承扩展 EMPS虽然可以直接对某个实体类型进行属性的扩展但是我们依然老的方案即使用CLR类继承机制扩展旧的实体。那么我们需要特别注意两种方案的区别 1. 属性扩展是直接对指定的领域实体进行扩展一旦扩展该领域实体类在整个应用程序中的属性都被扩展。 2. 而继承扩展则需要用于不同的领域实体中。 简单地说当你想在应用程序中扩展出一个新的领域实体类或者做一个全新的界面时则使用继承扩展。而当在做客户化时希望对现有的领域实体类进行完全扩展时则应该使用EMPS来进行属性扩展。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/911770.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站权重划分查找网站备案

一、自定义部件库 原则上尽量做到前后端分离,接口方便,复制简单。 1、单选框部件 # encoding: utf-8 ################################################### # 自定义的单选框 #################################################### 对外…

美妆网站怎么做鞍山做网站企业

如果把大模型训练比作 F1 比赛,长凡所在的团队就是造车的人,也是在比赛现场给赛车换轮子的人。1% 的训练提速,或者几秒之差的故障恢复时间,累积起来,都能影响到几百万的成本。长凡说:“大模型起来的时候&am…

网站建设所需网络营销是做什么

文章目录 260. 只出现一次的数字 III(字典 / 位运算)136. 只出现一次的数字(字典)137. 只出现一次的数字 II(字典)169. 求众数(字典)229. 求众数 II(字典)200…

做网站的公司 杭州如何创建一个网址

目录 ACM金牌带你零基础直达C语言精通-课程资料 一.作用域的基本概念 二.函数 1. 函数的定义和使用 2.为什么一定要有函数结构 3.形参与实参 4.函数的声明和定义 5.递归函数 此代码中递归函数执行流程: 练习:求斐波那契数列第n项的值: 欧几里…

个人动漫网站怎么做页面农村小工厂暴利

文章目录 [toc]试题编号试题名称时间限制内存限制题目背景问题描述输入格式输出格式样例输入样例输出样例说明子任务提示Python实现 试题编号 202305-1 试题名称 重复局面 时间限制 1.0s 内存限制 512.0MB 题目背景 国际象棋在对局时,同一局面连续或间断出现3次或3…

道滘东莞微信网站建设旅游网站优化方案

点击 <C 语言编程核心突破> 快速C语言入门 itoa函数的局限以及实现 前言一、功能描述二、具体实现对于第一版, 实现如下:第二版实现:测试用例: 总结 前言 把一个数用某种进制打印, 是一个很有用的功能, 值得庆幸的是, C语言有这么一个函数itoa(), 它可以把一个数转换为…

具身智能机器人架构:人形机器人系统架构深度拆解

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 35469554100490871 人形机器人市场规模多家咨询公司预测,2030-2033年间人形机器人的…

怎么查找网站死链指数函数和对数函数

分布式锁概念 在多线程环境下&#xff0c;为了保证数据的线程安全&#xff0c;锁保证同一时刻&#xff0c;只有一个可以访问和更新共享数据。在单机系统我们可以使用 synchronized 锁、Lock 锁保证线程安全。 synchronized 锁是 Java 提供的一种内置锁&#xff0c;在单个 JVM …

网站国内空间和国外空间培训机构网站源码

一般情况下&#xff0c;报错信息一大堆&#xff0c;值得注意的只有三个地方&#xff1a; 哪个文件发生了错误哪一行发生了错误错误原因是什么 只要知道这三个东西就能快速的定位到错误发生的位置并且根据提示解决。 如果你也喜欢我的这种异常输出(如文章顶部图) 那么可以参考以…

网站开发字典文档wordpress安全检测工具

Ubuntu安装好以后&#xff0c;默认是安装使用nano编辑器。不过这对于用惯了vim的人可能会有些不习惯。好在Ubuntu下安装vim还是比较简单的&#xff0c;使用如下命令即可&#xff1a;sudoapt-get install vim(apt-get install vim-full这下就好了 在输入 :syntax on 或者把/etc/…

php网站模板源码成都网站seo收费标准

一、引言 在Unity3D开发的MMORPG&#xff08;大型多人在线角色扮演游戏&#xff09;中&#xff0c;多玩家状态同步是一个至关重要的技术环节。它确保了在大量玩家同时在线时&#xff0c;服务器和客户端之间能够保持状态的一致性&#xff0c;从而提供流畅且准确的游戏体验。本文…

网站结构与导航设计杭州正晖建设工程有限公司网站

数据结构与算法 数据结构与算法是计算机科学中的两个核心概念&#xff0c;它们在软件开发和问题解决中起着至关重要的作用。 数据结构 数据结构是计算机中存储、组织和管理数据的方式&#xff0c;它能够帮助我们高效地访问和修改数据。不同的数据结构适用于不同类型的应用场…

内部网站 建设目标如何做后台网站的教程

王爱军 本文由国家能源集团信息技术主管王爱军投递并参与《2023中国数智化转型升级优秀CIO》榜单/奖项评选。丨推荐企业—锐捷网络 大数据产业创新服务媒体 ——聚焦数据 改变商业 随着全球信息化和网络化的进程日益加速&#xff0c;数字化转型已经成为当下各大企业追求的核心…

廊坊建设网站企业北京企业网站排名优化

PI校正环节在经典控制论中非常有用&#xff0c;特别是对负反馈控制系统&#xff0c;基本上都有PI校正环节。1.下面分别说明比例环节和积分环节的作用&#xff0c;以阶跃信号为例。①比例环节单独作用以上分析说明&#xff0c;若只有比例环节的控制系统&#xff0c;阶跃响应也是…

有什么网站可以做设计赚钱吗百度网站评价

1、概念介绍 Nginx ("engine x") 是一个轻量级、高性能的 WEB 服务器软件和反向代理服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的&#xff0c;第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。其将源代码以类 BSD 许可证的形式发…

卓驭,欧洲无绝境

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087 添加图片注释,不超过 140 字(可选)2025慕尼黑车展,卓驭任命Ni…

做游戏的网站有哪些广东东莞房价

mysql存储过程太慢的解决方法&#xff1a;首先打开my.cnf配置文件&#xff1b;然后添加配置【long_query_time1】&#xff1b;接着通过【tail -f /tmp/logs/mysqld.log】命令监控sql&#xff1b;最后进行针对性的优化即可。解决方法&#xff1a;第一步&#xff1a;修改/etc/my.…

仙桃做网站的公司有哪些wordpress 用户留言

回溯算法终于开始了&#xff01; 题目链接&#xff1a;leetcode 77. 组合 文章讲解&#xff1a;代码随想录 77. 组合讲解 视频讲解&#xff1a;带你学透回溯算法-组合问题&#xff08;对应力扣题目&#xff1a;77.组合&#xff09; 思路和解法 题目&#xff1a; 给定两个整…

英文网站公司公众号开发框架

1.前言 在12.0的系统rom定制化开发中,在定制recovery模块的时候,由于产品开发需要要求禁用recovery的相关功能,比如在通过adb命令的 adb reboot recovery的方式进入recovery也需要实现禁用,所以就需要了解相关进入recovery流程来禁用该功能 2.禁用adb reboot recovery命令…