zoukankan
html css js c++ java
反编译 Component重要类,全文解释 - 容器篇
using
System;
using
System.Security.Permissions;
namespace
System.ComponentModel
{
/**/
///
<summary>
///
容器类
///
</summary>
[HostProtection(SecurityAction.LinkDemand, SharedState
=
true
)]
public
class
Container : IContainer, IDisposable
{
/**/
///
<summary>
///
初始化对象
///
</summary>
public
Container()
{
//
用于锁定的锁定资源
this
.syncObj
=
new
object
();
}
/**/
///
<summary>
///
向容器添加新的组件
///
</summary>
///
<param name="component">
新加入的组件
</param>
public
virtual
void
Add(IComponent component)
{
//
Name为null处理
this
.Add(component,
null
);
}
/**/
///
<summary>
///
向容器添加新的组件并指定名称
///
</summary>
///
<param name="component">
新添加的组件
</param>
///
<param name="name">
组件的名称
</param>
public
virtual
void
Add(IComponent component,
string
name)
{
//
防止并发添加
lock
(
this
.syncObj)
{
//
允许component参数为null,并不出错,而是忽略
if
(component
==
null
)
{
return
;
}
ISite oldSite
=
component.Site;
//
如果新加入的组件包含了站点对象,且站点指向的就是自己,就不继续添加了;
//
说白了,就是不允许重复加入容器
if
((oldSite
!=
null
)
&&
(oldSite.Container
==
this
))
{
return
;
}
//
如果没有初始化过站点数组,就初始化4个
if
(
this
.sites
==
null
)
{
this
.sites
=
new
ISite[
4
];
}
else
{
//
??难度第一次就用校验名称了吗?
this
.ValidateName(component, name);
//
站点对象是存放在数组中的,所以当空间不足时,需要手工增大。
if
(
this
.sites.Length
==
this
.siteCount)
{
//
新的大小是原大小的2倍。
ISite[] newSites
=
new
ISite[
this
.siteCount
*
2
];
//
将原始数据复制到新的数组
Array.Copy(
this
.sites,
0
, newSites,
0
,
this
.siteCount);
this
.sites
=
newSites;
}
}
//
如果新加入的组件,原先有一个容器了,就应该从原容器中移除。不能有俩个老爸吧。
if
(oldSite
!=
null
)
{
oldSite.Container.Remove(component);
}
//
创建新的站点对象,这个CreateSite是可以重载的。
ISite newSite
=
this
.CreateSite(component, name);
//
增加站点计数器,并将新站点放在容器的最后。
this
.sites[
this
.siteCount
++
]
=
newSite;
//
为组件注射新的站点对象。
component.Site
=
newSite;
//
注意这里:他将components设置为null,以便Components属性重构数组的内容,
//
当现在就没有必要马上重构,优化
this
.components
=
null
;
}
}
/**/
///
<summary>
///
为新组件创建站点对象
///
</summary>
///
<param name="component">
要创建站点的组件对象
</param>
///
<param name="name">
组件预定的名称
</param>
///
<returns>
新的站点对象
</returns>
protected
virtual
ISite CreateSite(IComponent component,
string
name)
{
return
new
Container.Site(component,
this
, name);
}
/**/
///
<summary>
///
释放当前容器对象
///
</summary>
public
void
Dispose()
{
//
这个方法是不能重载的,但是他会调用下面的方法,而这个方法是可重载的。
this
.Dispose(
true
);
//
回收我吧。
GC.SuppressFinalize(
this
);
}
/**/
///
<summary>
///
重载此方法来释放自定义的资源
///
</summary>
///
<param name="disposing">
true表示调用方主动提出释放,false表示是垃圾回收器在调用此方法。
</param>
protected
virtual
void
Dispose(
bool
disposing)
{
//
只有主动要求释放的时候才会做这些事情。
if
(disposing)
{
//
锁定一下,并发小心啊。
lock
(
this
.syncObj)
{
int
i;
//
循环所有的子组件,将他们一一释放,也就是说,
//
我不能活,我的孩子们也要死。好残忍哦。
while
(
this
.siteCount
>
0
)
{
//
怎么喜欢联等号,看着不舒服,这个释放过程是从后向前释放的。
this
.siteCount
=
i
=
this
.siteCount
-
1
;
ISite site
=
this
.sites[i];
//
取消组件的站点引用,然后释放他。
site.Component.Site
=
null
;
site.Component.Dispose();
}
//
取消所有站点的引用,也就是取消了对所有子组件的引用。
//
虽然站点持有了容器的引用,但是现在容器不持有站点了,
//
也就取消了循环引用。
this
.sites
=
null
;
this
.components
=
null
;
}
}
}
/**/
///
<summary>
///
当容器被垃圾回收器回收前调用
///
</summary>
~
Container()
{
//
一般的,这个调用基本上没有什么事情可做。
this
.Dispose(
false
);
}
/**/
///
<summary>
///
获取服务
///
</summary>
///
<param name="service">
要获取的服务类型
</param>
///
<returns>
如果找到此服务就返回服务的实例,否则返回null
</returns>
protected
virtual
object
GetService(Type service)
{
//
在默认的Component实现中,他的GetService最终就是调用这个容器的GetService
//
所以,要为组件提供其他的服务,可以重载此方法已提供更多的服务
if
(service
!=
typeof
(IContainer))
{
return
null
;
}
return
this
;
}
/**/
///
<summary>
///
从容器中移除指定的组件
///
</summary>
///
<param name="component">
要移除的组件对象
</param>
public
virtual
void
Remove(IComponent component)
{
this
.Remove(component,
false
);
}
//
这个是实际的移除方法
private
void
Remove(IComponent component,
bool
preserveSite)
{
//
还是小心并发
lock
(
this
.syncObj)
{
//
允许参数为null,不出错,退出。
if
(component
==
null
)
{
return
;
}
//
获取要移除的组件站点对象
ISite oldSite
=
component.Site;
//
没有站点对象,不关我的事情,退出
if
(oldSite
==
null
)
{
return
;
}
//
不是我容器下的东西,也不关我的事情,退出
if
(oldSite.Container
!=
this
)
{
return
;
}
//
首先组件的站点对象,不再指向他。
if
(
!
preserveSite)
{
component.Site
=
null
;
}
//
找到他,移除的时候比较简单,并不调用他的Dispose方法,奇怪。
for
(
int
i
=
0
; i
<
this
.siteCount; i
++
)
{
if
(
this
.sites[i]
==
oldSite)
{
//
减少计数器
this
.siteCount
--
;
//
将删除的位置之后的数据向前移动一个。
Array.Copy(
this
.sites, (
int
)(i
+
1
),
this
.sites, i, (
int
)(
this
.siteCount
-
i));
//
将最后一个站点设置为空
this
.sites[
this
.siteCount]
=
null
;
//
内容发生变化,设置components为null,以便重新构建
this
.components
=
null
;
return
;
}
}
}
}
/**/
///
<summary>
///
移除组件,但不删除组件的站点属性。
///
</summary>
///
<param name="component">
要移除的组件
</param>
protected
void
RemoveWithoutUnsiting(IComponent component)
{
//
这是一个特殊的方法,不知用在什么地方。
this
.Remove(component,
true
);
}
/**/
///
<summary>
///
校验新加入的组件的名称正确性
///
</summary>
///
<param name="component">
要校验的组件
</param>
///
<param name="name">
组件的名称
</param>
protected
virtual
void
ValidateName(IComponent component,
string
name)
{
//
参数校验
if
(component
==
null
)
{
throw
new
ArgumentNullException(
"
component
"
);
}
//
没有名字,不算有问题
if
(name
!=
null
)
{
//
循环所有的站点。但不明白的是为什么要取站点的最小值和数组的最小值,难道siteCount不是总是小于sites.Length的吗?
for
(
int
i
=
0
; i
<
Math.Min(
this
.siteCount,
this
.sites.Length); i
++
)
{
ISite site
=
this
.sites[i];
//
如果 站点有效 且
//
站点有名字 且
//
站点的名字和新名字相等 且
//
站点对应的组件不是检查的组件(自己)。
if
(((site
!=
null
)
&&
(site.Name
!=
null
))
&&
(
string
.Equals(site.Name, name, StringComparison.OrdinalIgnoreCase)
&&
(site.Component
!=
component)))
{
//
该组件会被继承并且是只读的,就不报错,Why?
InheritanceAttribute attribute1
=
(InheritanceAttribute)TypeDescriptor.GetAttributes(site.Component)[
typeof
(InheritanceAttribute)];
if
(attribute1.InheritanceLevel
!=
InheritanceLevel.InheritedReadOnly)
{
throw
new
ArgumentException(
"
名字重复了
"
, name);
}
}
}
}
}
/**/
///
<summary>
///
获取容器的所有组件
///
</summary>
public
virtual
ComponentCollection Components
{
get
{
//
组件集合是动态创建的。
ComponentCollection retCollection;
lock
(
this
.syncObj)
{
if
(
this
.components
==
null
)
{
//
创建一个数组,将所有的站点的组件对象收集起来
IComponent[] newComponents
=
new
IComponent[
this
.siteCount];
for
(
int
i
=
0
; i
<
this
.siteCount; i
++
)
{
newComponents[i]
=
this
.sites[i].Component;
}
//
这个赋值好像早了点,因为如果过滤服务失败,下次方法Components时就时错误的结果了,
//
因为comonents已经不是null了。
this
.components
=
new
ComponentCollection(newComponents);
//
初始化状态checkedFilter为false,所以即使下面的条件不通过,也还是会去申请的。
//
如果申请过了,但是上次没有申请到,就重新申请。
//
只要有一次成功申请到,就不会再申请了。
if
((
this
.filter
==
null
)
&&
this
.checkedFilter)
{
this
.checkedFilter
=
false
;
}
}
//
如果没有申请过过滤服务,就申请一次。
if
(
!
this
.checkedFilter)
{
//
缓存过滤服务,总觉得缓存危险
this
.filter
=
this
.GetService(
typeof
(ContainerFilterService))
as
ContainerFilterService;
this
.checkedFilter
=
true
;
}
//
过滤服务有效
if
(
this
.filter
!=
null
)
{
//
过滤数据,过滤有结果,才放入新结果
ComponentCollection newCollection
=
this
.filter.FilterComponents(
this
.components);
if
(newCollection
!=
null
)
{
this
.components
=
newCollection;
}
}
retCollection
=
this
.components;
}
return
retCollection;
}
}
//
Fields
private
bool
checkedFilter;
//
申请过过滤服务吗
private
ComponentCollection components;
//
缓存的组件集合
private
ContainerFilterService filter;
//
缓存的过滤服务
private
int
siteCount;
//
当前站点总数
private
ISite[] sites;
//
当前所有的站点存放处(可能有空地)
private
object
syncObj;
//
锁定对象
/**/
///
<summary>
///
内置的站点对象,不需要公开的.
///
</summary>
private
class
Site : ISite, IServiceProvider
{
/**/
///
<summary>
///
初始化站点
///
</summary>
///
<param name="component">
站点对应的组件
</param>
///
<param name="container">
所在容器
</param>
///
<param name="name">
新的名称
</param>
internal
Site(IComponent component, Container container,
string
name)
{
this
.component
=
component;
this
.container
=
container;
this
.name
=
name;
}
/**/
///
<summary>
///
获取服务
///
</summary>
///
<param name="service">
服务类型
</param>
///
<returns>
服务实例
</returns>
public
object
GetService(Type service)
{
//
如果申请的是ISite,就是自己了.
if
(service
!=
typeof
(ISite))
{
//
实际调用的是容器的GetService
//
Component的GetService调用顺序是:
//
Component.GetService -> Site.GetService -> Container.GetService
return
this
.container.GetService(service);
}
return
this
;
}
/**/
///
<summary>
///
返回站点关联的组件
///
</summary>
public
IComponent Component
{
get
{
return
this
.component;
}
}
/**/
///
<summary>
///
返回站点所在的容器
///
</summary>
public
IContainer Container
{
get
{
return
this
.container;
}
}
/**/
///
<summary>
///
返回是否是设计模式
///
</summary>
public
bool
DesignMode
{
get
{
//
总是返回false,真的不知道为什么设计成一个属性,而不是GetService(IDesignService)的方式。郁闷
return
false
;
}
}
/**/
///
<summary>
///
返回/设置站点的名称
///
</summary>
public
string
Name
{
get
{
return
this
.name;
}
set
{
//
校验名称,名字只会存储在这里。
if
(((value
==
null
)
||
(
this
.name
==
null
))
||
!
value.Equals(
this
.name))
{
this
.container.ValidateName(
this
.component, value);
this
.name
=
value;
}
}
}
private
IComponent component;
private
Container container;
private
string
name;
}
}
}
查看全文
相关阅读:
【Oracle】安装
【Java】String,StringBuffer与StringBuilder的区别??
【Java】基本数据类型长度
静态构造函数
【算法】递归算法
【JavaScript】JavaScript教程之------------------JavaScript实现
【Android】listview优化
【JAVA EE企业级开发四步走完全攻略】
Eclipse下Tomcat插件的安装
Android工具
原文地址:https://www.cnblogs.com/tansm/p/303525.html
最新文章
Zabbix的API的使用
Zabbix低级主动发现之MySQL多实例
Zabbix监控Windows主机
Zabbix自动发现与主动注册
苹果MAC安装Windows系统
Zabbix监控主动模式
Zabbix监控web,MySQL,TCP状态,Nginx
Zabbix使用SMTP发送邮件报警并且制定报警内容
CentOS7修改系统时区
无敌JS关闭当前窗口代码,不弹出确认提示
热门文章
jqprint网页打印时有页码和URL
Arcmap10.1下安装ArcBrutile0.2.2 (Win7)(转)
lbypmall系统备份恢复
操盘策略:如何从上下影中捕捉战机
dede数据库类使用方法 $dsql(转)
svn服务器端回退版本 (转)
Dedesql数据库类详解(二次开发必备教程)(转)
photoshop画矩形款
【Hybrid App】Hybrid App开发 四大主流移平台分析
【JavsScript】关于javascript的路线
Copyright © 2011-2022 走看看