.net framework 2.0 概论 (framework的设计与应用 学习笔记)

Assemblys

IL Code 是CLR的核心

但CLR无法直接加载只包含IL Code的文件

IL Code必须被放置到一个Module中

Module必须被放置到一个Assembly中

Assembly就是一个类似DLL Exe的文件

就像Windows中的EXE及DLL一样,可运行的Assembly中包含着一个Module,其中包含着一个Entry Pointing(程序启动点),当CLR加载可运行的Assemlby后会由此开始运行。

Assembly 结构

Assembly实际上只是一个PE格式的文件

Assembly结构图
PE Header
CLR Header
CLR  Metadata
Manifest
Modules  |   Resources


Module 结构图


PE Header
Stub  (这里面的数据用来加载CLR环境,CLR加载完毕后,会加载紧随其后的IL Code,并转译成Native Code 来运行,这个转译操作由JIT Compiler来运行)
CLR Header
IL Code

Strong-Name  Assembly

在VS 2005中,通过项目的属性页来产生签名文件,然后套用到项目产生的Assembly中.

加载 Assembly

静态加载 动态加载

动态加载 : 用Assembly.Load函数来加载Assembly.

当使用动态加载时,由于编译时期Assembly A 并未被加载,所以将无法通过编译,程序用必须以Assembly.Load函数加载该Assembly A,通过返回的Assembly对象的GetType 函数来取得Class1的Type对象,再经由Activator.CreateInstance函数来创建Class1的对象实例


Application Domain 与 Thread

在Win32时代,应用程序运行在Process的Thread中,一个Process可以创建多个Thread以及子Process.

在.net 中Process有AppDomain取代。

如此设计解决两个问题:

(1):创建Process耗时耗资源,在一个Process中创建多个 appDomain的方式,可以减少Process.
 (2):  跨进程 (Cross-Process)调用,耗时,由于AppDomain在同一进程中,问题则不存在。

跨AppDomain效率仍然比较差的,当使用来自另一个AppDomain中的对象时,实际上取得的是一个Proxy对象,由Proxy对象进行中介操作,也由于要创建Proxy对象,加上所有调用都要转成消息的缘故,效率也是比较差的。所以应避免跨AppDomain调用的产生.

Applicaton Domain

process可以有多个appDomain ,每个AppDomain可以有多个 Thread对象。

AssemblyLoad 触发于AppDomain载入一个Assembly时
DomainUnload 触发于AppDomain卸载时,也就是Unload函数被调用或是该AppDomain被消灭前
ProcessExit 当默认的AppDomain被卸载时触发,多半是应用程序退出时

一般的应用程序使用AppDomain的机会并不大,大多数的应用只是挂载事件至DomainUnload来处理当AppDomain卸载时的清除工作,或是挂载到 ProcessExit来处理应用程序退出前的清除工作哦。

Threads

CLR中的线程并不等同OS中的线程。

当使用Thread时,程序员必须注意 同步处理 问题

.net 提供了四种同步机制

Monitor
Mutex
ReaderWriterLock
Semaphore

Monitor

最常用最基本的同步机制。

例子:

lock(variable)
{
i=100;
}
 编译器会转化成:

Monitor.Enter(variable)
try
{
 i=100;
}finaly
{
 Monitor.Exit(variable);
}

Attributes
标签

看看Attributes能做什么

用户定义的Attribute必须继承至System.attribute类
 1using System;
 2using System.ComponentModel;
 3
 4namespace AttributeFullDemo
 5{
 6    [attributeUsage(AttributeTargets.Class,Inherited=false,allowMultiple=false)]
 7    
 8    public class ClassShowProcessAttribute:Attribute
 9    {
10        private bool _show=false;
11            
12        public bool Show
13        {
14            get
15            {
16                return _show;
17            }

18        }

19        
20        public ClassShowProcessAttribute(bool show)
21        {
22            _show=show;
23        }

24        
25        [ClassShowProces(true)]
26        public class ClassA\
27        {
28        }

29    }

30}
    
31    
32    
33    

AttributeUsage 代表着此Attribute的使用情况

AttributeTargets 该Attribute 的适用范围,可以是类、函数、属性
Inherited 此Attribute 被贴到目标物上,目标类的子类是否继承此attribute
AllowMultipe  是否允许重复贴


在.net 2.0中,可以用Attribute .IsDefine函数来判断此类型中拥有哪些Attribute ,再使用
Attribute.GetCustomAttributes函数来取得Attribute 对象。

使用范例:

 1using System;
 2
 3namespace AttributeFullDemo
 4{
 5    [ClassShowProcess(true)]
 6    public class AttrClassTest
 7    {
 8        public AttrclassTest()
 9        {
10        }

11    }

12}

程序中创建了一个Object对象,放入两个AttrClassTest对象及一个String 对象

用 Attribute.IsDefine函数来判断该对象类型是否标记了ClassShowProcessAttribute,
然后以Attribute.GetcustomAttributes函数来取得Attribute对象。    


Attribute 绑定到成员变量上

 1using System;
 2using System.componentModel;
 3using System.Reflection;
 4
 5namespace attributeFullDemo
 6{
 7    public interface IFieldShow
 8    {
 9        string Show(object o);
10    }

11    
12    [AttributeUsage(AttributeTargets.Field|attributeTargets.Property,Inherited=false,AllowMultiple=false)]
13    
14    public class FieldShowAttribute:Attribute
15    {
16        private bool _show=false;
17        private Type _showClass=null;
18        
19        public bool Show
20        {
21            get
22            {
23                return _show;
24            }

25        }

26        
27        public  Type  ShowClass
28        {
29            get
30            {
31                return _showClass;
32            }

33        }

34        
35        public IFieldShow CreateShowInstance()
36        {
37            object o;
38            
39            ConstructorInfo  cinfo=_showClass.GetConstructor(new Type[]{});
40                
41            o=cinfo.Invoke(null);
42                
43                return (IFieldShow)o;
44                
45        }

46        
47        public FieldShowAttribute(bool show,Type showClass)
48        {
49            _show=show;
50            _showClass=showClass;
51            
52            if(_showClass==null)
53            {
54                throw new Ecepton("must provides showClass!");
55            }

56        }

测试类:
 1using System;
 2using System.ComponentModel;
 3
 4namespace AttributeFullDemo
 5{
 6    public class StringFieldShow:IFieldShow
 7    {
 8        string IFieldShow.Show(object o)
 9        {
10            return o.ToString();
11        }

12        
13        public class AttrFieldTest
14        {
15            [FieldShow(true,typeof(StringFieldShow)]
16            
17            public int _number=0;
18            
19            
20            public AttFieldTest()
21            {
22            }

23        }

24    }

25}


上面的例子中展现了另一种Attribute类型的应用,其接受一个Type 参数,代表着程序员在使用此Attribue时可以指定一个自定义的Type来改变其显示的行为。
程序员也可以提供一系列的预先定义的type供用户使用,这将Attribute带往另一个复杂且高扩展性的应用面。
在下面的例子中展示

 1private static void TestField()
 2{
 3    AttrFieldTest[] o=new AttrFieldTest[]{new AttrFieldTest(),new AttrFieldTest()};
 4    
 5    o[0]._number=15;
 6    o[1]._number=30;
 7    
 8    foreach(AttrFieldTest item in o)
 9    {
10        foreach(FieldInfo field in item.GetType().GetFields())
11        {
12            if(Attribute.IsDefined(field,typeof(FieldShowAttribute))) //如果定义了"FieldShowAttribute"标签
13            {
14                FieldShowattribute[] fattr=(FieldShowAttribute[])Attribute.GetCustomAttributes(field,typeof(FieldShowAttribute),false);
15                //把FieldShow Attribute类型的标签放入FieldShowAttribute数组中
16                
17                if(fattr.Lenth!=0)
18                {
19                    Console.WriteLine(field.Name+"="+fattr[0].CreateShowInstance().Show(field.GetValue(item)));
20                }

21            }

22        }

23    }

24}

25

这种概念将原本由客户端处理的工作交由另一个类处理,可以有效的切割应用程序,給予较高的扩展性及明确的定位。

不过此范例不是一个良好的设计,因为其在寻找Attribute时会为每一个Attribute.Type创建一个实例。有滥用内存之嫌疑,要改善这一点,程序员可以在Attribute中定义一个静态函数,并要求传入的attribute.Type类型必须拥有一个处理的静态函数
posted on 2007-12-30 11:03  蓝蓝的天2016  阅读(276)  评论(0)    收藏  举报