.NET/ASP.NETMVC Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(一)
.NET/ASP.NETMVC Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(一)
阅读目录:
- 1.开篇介绍
- 2.Model与View的使用关系(数据上下文DataContext与View呈现)
- 3.Metadata元数据驱动设计(如何使用中间层元数据来驱动最终的行为)
- 4.ASP.NETMVC ModelMetadata(ModelMetadata元数据如何支撑Model与View之间的组合关系)
1】开篇介绍
这篇文章让我们一起来学习一下有关Asp.netMvc中的Mode元数据的相关设计和围绕元数据的一些其他对象模型,他们是如何通过彼此协调来支撑起一个灵活的界面编程接口;
其实提到元数据(Metadata)大家在研究某个应用框架的时候都曾经或多或少的见到过,可能并没有引起你的注意;其实在很多应用框架中我们都能看见Matedata的影子,它是一个很不错的框架设计模式,俗称:“元数据驱动设计”,它跟目前很多设计思想很接近,如:元编程、契约式设计,这些模式目的都是为了能很好的控制耦合,产生极大的扩展灵活性;元编程让我们能基于最终的用户选择动态的产生运行软件的代码,而契约式设计能让我们将控制权设立在很远的地方,从而很大粒度的控制扩展性,根据契约设立规则,控制端再在运行时动态的生成出最终需要的规则;
通过对这些模式深入理解,基本上可以提炼出两条设计上的黄金规则:1.将变化点从编译时迁移到运行时;2.将变化点从硬编码迁移到配置化;
这里只是一个简单的介绍,由于每一个主题细化下来都会很大,都会包含该方向中的很多领域概念、术语和重要的设计思想,所以这里只是一个简单的介绍,本篇文章会重点介绍一下“元数据驱动设计”编程思想和它到底好在哪里,然后在ASP.NETMVC中它起到怎样的作用,它又是如何架起通往Model与View的高速桥梁的,让Model与View可以到做1对N的搭配关系,在大型站点中ViewModel一般只有固定的几种,但是View可能会有成千种,如何做到这种高度适配,这就是自定义模板的功能,当然一切都建立在ModelMetadata基础上;
2】Model与View的使用关系(数据上下文DataContext与View呈现)
在MVC的定义中,Model准确点讲是ViewModel而非DomainModel,ViewModel简称显示Model,主要是将要显示的数据融合在一个DataContext中,它来源于企业应用架构中的Query端的数据源;一般情况下这样的一个ViewModel不会经常变化,都是根据众多的业务场景抽象出来的一个比较Common的数据上下文;
在网站型的系统中,尤其电子商务平台,界面的变化很常见,几乎每天都有可能改变界面上的某个显示方式,同样一组数据可能在UI上的展现方式各不相同;这里就会形成一个Model与多个View的组合关系,同样一个Promotion(促销)数据上下文,需要在很多注销类别不同的UI上展现,而不同的UI组成都是由不同的View的负责生成;
图1:
可以总结出一个数据上下文实体在大部分的情况下都可能会被很多View使用,所以ASP.NETMVC 需要具备很强的自定义性,一个Model可以随意呈现出多中Ui而不会因此将ViewModel搞的一团乱;
注意:一个ViewModel数据实体可能很大,如果为了应付不同的显示场景最好将ViewModel进行切割,拉出继承体系,而不是将所有的ViewModel耦合在一个超大的ViewModel中,这样会让每一次的查询都会涉及到一些你本次不相关的属性;
3.Metadata元数据驱动设计(如何使用中间层元数据来驱动最终的行为)
元数据驱动设计模式是众多经典框架设计模式之一,它与契约式设计有点一脉相承的感觉;其实框架设计的本质是如何灵活的运用一些框架设计模式,不同的语言、平台对模式的运用各不相同,但是模式的中心思想一直不会变,不管你如何设计都必须呈现出框架模式的本质才行;
在众多的框架设计模式中 如:契约式设计、元编程、元数据驱动设计、管道模型、远程代理模式、提供程序模型;元数据驱动设计模式是使用频率比较高的,因为其复杂度也相对较低所以比较容易上手;其实在很多现有的.NET框架中,如:WCF、ASP.NET、Remoting、Winform中都会看见Metadata的影子,但是不一定非得要在命名的时候加上Metadata,有很多的时候也会使用Description来代替;
元数据通常作为支持数据,它是描述数据的数据,是真正被解析处理的数据;既然是描述数据的数据,那么就存在它在那个方向上的描述,描述的角度是什么,描述的层面又是是什么;
我们就拿ModelMetadata来讲,在ASP.NETMVC中,Model的使用方向基本上被限定在三个操作集合中,第一:请求的数据绑定,第二:数据绑定时的验证,第三:Model的最终呈现;那么ModelMetadata要包含这三个操作集合所需要的全部数据,当然也可以通过切割成三组元数据对象模型,通过继承体系包含起来;那么ModelMetadata需要描述三个方向上的所需要的数据集合,Model本身就是一中数据,而通过使用ModelMetadata来抽象的描述第二个层面上的数据,从三个操作集合角度中包含使用的数据,也就是说三个角度,两个层面;如果你的框架需要具备多个层面,那就需要进一步细化抽象;
图2:
标准数据经过一个中间的环节转换成元数据,然后交给最终的处理程序去使用;可以很清晰的了解到元数据起到的一个核心作用,它可以很好的将处理程序与标准数据之间解耦,让中间的元数据提供更大的灵活性,通过这个中间层元数据,我们可以很轻松的做到对元数据进行配置;
我们假设没有中间层元数据,操作程序不管如何设计都会和标准数据实体有耦合,而且要保证标准数据的纯洁度,不可能总是对它使用继承、特性等重度污染性的侵入,保证完全的POCO(Plain Old Csharp Objects)对象很难,如果没有IDE的编译时支持,很难提取出可以在运行时使用的数据;这个时候我们如果需要修改标准元数据的类型或者修改操作程序的逻辑都会或多或少的对两者有影响;
如果使用元数据我们完全可以将表数据对元数据的定义部分迁移到配置文件中去,然后再在元数据提供程序中扩展读取元数据的源头,可以做到将标准数据放在任何地方甚至遥远的云平台上,对于操作程序来说,我们可以将获取元数据的接口提取成Service方式,从任何一个地方读取元数据;
这些种种方案你可能决定永远都不会用到,但是谁又能把某个框架的所有功能都用一边呢,系统需求各异,都有可能需要这些扩展点;
4.ASP.NETMVC ModelMetadata(ModelMetadata元数据如何支撑Model与View之间的组合关系)
未完待续,敬请关注......
分布式唯一ID生成服务
SNService是一款基于分布式的唯一ID生成服务,主要用于提供大数量业务数据建立唯一ID的需要;服务提供最低10K/s的唯一ID请求处理.如果你部署服务的CPU资源达到4核的情况下那该服务最低可以提供100K/s的请求处理能力.服务支持部署到Linux mono 3.2.3和Windows .Net4.0
ID生成规则
服务生成的ID是64位无符号长整型,其中48位是现有时间和2013年1月1日时间差的毫秒数,另外16位则是针对当前毫秒的递增值.即每毫秒支持6万多个唯一ID生成,每秒则支持多达6千万个ID生成.这个数量级足可以满足大部份的需要.
为了保证所有服务器上的业务数据获取得全局唯一ID,所以通过服务的方式提供.如果考虑更大的获取量和服务的可靠性,可以部署两台ID生成服务,分别生成序列为奇和偶数,应用端通过虚拟IP指向即可.
可以通过修改以下配置项来确定递增值的起始和步增长值
<sNServiceSection xmlns="urn:IKende.com.SNService">
<sequence start="1" step="1"/>
</sNServiceSection>
如果生成规则不满足需要,则可以自行修改ID生成方式
部署服务
服务是通过TCP的方式提供访问,分别提供Console和windows service两种方式来加载服务.可以通过修改以下配置来改动服务监听的IP和端口,默认情况下是监听本机所有IP和8088端口.
<serverSection xmlns="urn:Beetle.Express">
<listens>
<add name="SN_SERVER" type="TCP" port="8088" handler="IKende.com.SNService.SNServer,IKende.com.SNService" syncSend="true" useReceiveQueue="false" useSendQueue="false"/>
</listens>
</serverSection>
服务的执行情况可以通过程序或服务目录下的log目录查看日志.
[注意:由于ID是通过时间截来处理,所以在部署前需要同步一下网络时间,保证以后即使服务重启也不会导致ID生成上出现问题.]
调用
服务通过TCP方式提供,所以只需要TCP接入到相关服务并发送GETSN指令,服务即可响应BYTE[8]ulong的数据.如果是使用.NET访问那可以引用IKende.com.SNService.dll.,通过以下代码来获取唯一ID.
private static IKende.com.SNService.Api.SNClient client=new Api.SNClient("127.0.0.1", 8088); ulong value = client.GetValue();
提供.NET平台下高吞吐的网络通讯应用技术咨询和支持
开源多台平通讯组件
c#组件设计交流群:47164588
c# socket :136485198 微博http://weibo.com/ikende
.NET/ASP.NETMVC Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(一)的更多相关文章
- MVC中Model元数据及绑定机制
ASP.NET MVC的Model为View Model,表示最终呈现在View上的数据,而Model元数据的一个重要的作用在于控制对象在View上的呈现方式.说得更加具体点,就是基于某种数据类型的M ...
- .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(三)
阅读目录: 7.HtmlHelper.HtmlHelper<T>中的ViewModel的类型推断 8.控制ViewModel中的某个属性的呈现(使用PartialView部分视图细粒度控制 ...
- .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)
阅读目录: 1.需求背景介绍(Model元数据设置项应该与View绑定而非ViewModel) 1.1.确定问题域范围(可以使用DSL管理问题域前提是锁定领域模型) 2.迁移ViewModel设置到外 ...
- 【笔记】ASP.NET MVC Model元数据
问题1:什么叫Model元数据? Model元数据,是针对数据类型的一种描述信息.由于复杂类型(或者说类型嵌套的存在,比如CustomerModel中有一个属性为复杂类型Address)的存在,因此M ...
- ASP.NET MVC Model元数据(五)
ASP.NET MVC Model元数据(五) 前言 在上一篇中我们描述了应用于Model上面的各种用于显示控制的特性类,在本篇中将详细的介绍这些特性类的应用,虽然它们跟Model元数据的直接关系并不 ...
- ASP.NET MVC Model元数据(四)
ASP.NET MVC Model元数据(四) 前言 前面的篇幅讲解了Model元数据生成的过程,并没有对Model元数据生成过程的内部和Model元数据结构的详细解释.看完本篇后将会对Model元数 ...
- ASP.NET MVC Model元数据(三)
ASP.NET MVC Model元数据(三) 前言 在上篇中我们大概的讲解了Model元数据的生成过程,并没有对Model元数据本身和详细的生成过程有所描述,本篇将会对详细的生成过程进行讲解,并且会 ...
- ASP.NET MVC Model元数据(二)
ASP.NET MVC Model元数据(二) 前言 在上篇中,给大家留个对Model元数据的印象,并没有对Model元数据有过多的讲解,而在本篇中也不会对Model元数据的本身来解释,而是针对于它的 ...
- ASP.NET MVC Model元数据(一)
ASP.NET MVC Model元数据(一) 前言 在我初学的时候对Model元数据的概念很模糊,或者说是在大脑中没有它的一个模型,作为小白的我去看网上的一些文章还是两眼一黑啥都看不明白,然后我想退 ...
随机推荐
- Angularjs,WebAPI 搭建一个简易权限管理系统
Angularjs,WebAPI 搭建一个简易权限管理系统 Angularjs名词与概念(一) 1. 目录 前言 Angularjs名词与概念 权限系统原型 权限系统业务 数据库设计和实现 Web ...
- VS扩展开发框架
VsSharp:一个VS扩展开发框架(上) 上篇:设计 一.引子 自2008年起开发SSMS插件SqlSharp(er)的过程中,有一天发现多数代码都大同小异,就像这样. Commands2 comm ...
- DropDownListFor使用ViewData进行绑定的示例
特别注意,经实践: 此方法的ViewBag的名称必须和new SelectList()中的最后一个参数,即下拉框的默认值的名称必须相同,如: ViewBag.Title = WebConst.UnSe ...
- oracle_修改Oracle数据库字符集 AL32UTF8;
修改数据库字符集 以支持维文等 utf8 停掉库 进入装载模式 ALTER SYSTEM ENABLE RESTRICTED SESSION; ALTER SYSTEM SET JOB_QUEUE_ ...
- <七>阅读<<大话设计模式>>该模板模型
哈哈,没想到.在不知不觉中拥有第七书面文章,看来我仍然非常有毅力. 上坚持一件事非常easy,仅仅要你每天不断的朝着自己的目标出发,不论什么事情都不会挡着你.好了大道理不多说,谁都懂.那看看这个模板模 ...
- Dom中的nodeName、nodeValue 、nodeType
nodeName.nodeValue 以及 nodeType 包含有关于节点的信息. nodeName 属性含有某个节点的名称. 元素节点的 nodeName 是标签名称 属性节点的 nodeName ...
- CSS hack 如何区分所有IE浏览器和非IE浏览器
网上方法很多,例如,测试后得出以下结论,多余的话不说了,直入主题: 1.所有的推理IE浏览器 正解:此写法仅仅被lE浏览器识别,非IE浏览器不识别. <!--[if IE]> <st ...
- 解决tomcat占用8080端口
怎么解决tomcat占用8080端口问题图文教程 怎么解决tomcat占用8080端口问题 相信很多朋友都遇到过这样的问题吧,tomcat死机了,重启eclipse之后,发现 Se ...
- 【百度地图API】建立全国银行位置查询系统(二)——怎样为地图添加控件
原文:[百度地图API]建立全国银行位置查询系统(二)--怎样为地图添加控件 <摘要>你将在第二章中学会以下知识: 使用手写代码的利器——notepad++: 如何为地图添加控件——鱼骨. ...
- tinyxml 查找element
下面这段代码是网上找来的,很是经典 bool GetNodePointerByName(TiXmlElement* pRootEle, const char* strNodeName,TiXmlEle ...