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;
}
}
}
查看全文
相关阅读:
1.8新特性
线程池
微服务简介
缓存三大问题
Redis分布式锁的正确实现方式
【java-10&11&12】java语言(Hello World相关)
【postman】postman 安装失败
【java-04-09集】JDK的下载和安装&配置环境变量(临时和永久)&命令行方式
【ISTQB】TM&TA&TTA区别
【git】学习地址
原文地址:https://www.cnblogs.com/tansm/p/303525.html
最新文章
sp<> 强指针类的用法
:: 操作符
CRM系统之stark组件流程分析
03 爬虫之selenium模块
Django中CBV及其源码解释
Django中模型层中ORM的多表操作
Django中模型层中ORM的单表操作
02 爬虫数据解析之re,xpath,beautifulsoup
jquery选择器和基本操作
会议室预定
热门文章
Django中cookie&session的实现
矩阵相乘
【并查集】【基本操作】
数据结构
【模板】线段树
不涉及算法的计算机要点总结
疑问
链表-(qb讲课)
由 树的带权重心 衍申的对 树状DP 的感悟
CAS
Copyright © 2011-2022 走看看