惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
aimingoo的专栏
aimingoo的专栏
F
Fortinet All Blogs
Blog — PlanetScale
Blog — PlanetScale
GbyAI
GbyAI
MongoDB | Blog
MongoDB | Blog
月光博客
月光博客
The Cloudflare Blog
量子位
T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
MyScale Blog
MyScale Blog
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
G
Google Developers Blog
D
DataBreaches.Net
V
Visual Studio Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
U
Unit 42
博客园 - 聂微东
有赞技术团队
有赞技术团队
A
About on SuperTechFans

博客园 - 栖息的熊

Mark一些关于线程同步的信息 【转载】安卓巴士Android开发神贴整理 关于Join 异常诡异的mysql连接异常:Fatal error encountered during command execution. 误人子弟的面试题答案 .Net中的安全机制 用重载操作符实现用户数据类型的转换 override和new关键词的差别 你必须知道的值传递和引用传递 windows用户配置文件的复制 求职:本人从事3年工作流引擎开发,熟悉XPDL,.net3.5中WF,Biztalk,开源工作流引擎OBE,期望工作地点上海 对Activity副本的再理解 Windows Workflow Foundation中实现人工活动的demo,按照XPDL规范的实现 WF消息队列的使用 查数据库死锁的实际例子 喜欢使用VMware的.net程序员要注意呀(Visual Studio启动不了的问题) 编译器错误信息: CS1595: 已在多处定义“ ”;一种可能出现的情况 BPM业务场景分析(1)——内部交易合并开票 高级工作流模式深入业务场景分析(1)——多路合并
用定制特性规范构件调用
栖息的熊 · 2008-10-10 · via 博客园 - 栖息的熊

     在GSP平台中,构件扮演着让平台更灵活,让用户需求更容易变化的重要角色,.net方法的调用,用户自定义窗体的展现等等都是最常见的应用场景。但由于我们的构件平台能力较弱,长久以来构件平台只是起着通用反射调用器的作用。让构件标准化,是我们发展构件平台的必经之路。这篇文章只是从使用定制特性这个角度来增强构件的标准化程度。

     定制特性从我的角度理解,就是给程序集、类型、方法、属性等等元素加上的辅助信息,我们可以告诉调用者调用前要做什么,调用后再做什么,或者是要让编译器做什么等等。我们经常使用的是.net framework中已经存在的特性,而自己定制特性的场景还很少。

     下面我描述一下我们在构件使用过程中的两个问题,并说明如何使用特性来解决:

1、在工作流的人工活动节点上,我们需要用户定义一个单据,作为人工执行工作的一个数据参考。这里需要传入一些参数(权限、取数条件、单据分类等等),我们的构件平台将窗体描述为构件,描述信息中包含了如何调用这个窗体的信息。但在实现时却有小小的限制,对于web窗体使用URL后跟参数的方式就可以很好的实现,而对于winform窗体,就必须要求与参数匹配的构造函数。但是很多单据的作者却更喜欢将这些参数实现为属性,而非构造函数中的参数。这样的情况我们除了强识别形参名称,并与窗体属性一致,就没有太好的办法。

2、与1中类似的情况,我们给这些构件的形参定义实参是,一般情况下是使用单据数据Schema中的字段,但这个过程也是把我们最终用户晕头转向,除非我们约定形参名称必须与Schema中的字段匹配,不然我们也不好解决这个问题。

     以上两个问题都可以用定制特性的方式,稍微优雅一些的解决。我们设计下面的特性:

[AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=false)]
class GspParamsAttribute:Attribute
{
    private string paramName;

    public string ParamName
    {
        get { return paramName; }
        set { paramName = value; }
    }

    private string actualParamName;

    public string ActualParamName
    {
        get { return actualParamName; }
        set { actualParamName = value; }
    }

    private string actualParamPath;

    public string ActualParamPath
    {
        get { return actualParamPath; }
        set { actualParamPath = value; }
    }
}

[AttributeUsage(AttributeTargets.Class)]
class GspSupportParamSpecifyAttribute : Attribute
{
}

     对于单据的作者,就可以这样标记他的单据:

[GspSupportParamSpecify()]
class MyForm:Form
{
    private string someProperty;

    [GspParams(ParamName="SomeProperty",ActualParamName="OtherProPerty")]
    public string SomProperty
    {
        get { return someProperty; }
        set { someProperty = value; }
    }
}

     对于我们的构件设计器,就发现了一个需要在GSP平台中作为参数的属性SomProperty;对于流程设计在引用这个构件配参数时,就发现需要在Schema中找OtherProPerty字段作为实参来配置这个形参;对于构件调用的运行时,在发现GspSupportParamSpecify特性时,就知道这个类型中的某些属性需要被赋值,进而又从SomProperty属性上发现了GspParams特性,就知道使用哪个参数来给这个属性赋值了。

     而发现特性,需要使用反射,Type类型为我们提够了足够的信息,使用Attribute.GetCustomAttribute()的多个重载,可以方便我们运用于多个场景。