反编译 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, 0this.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;
        }

    }

}

原文地址:https://www.cnblogs.com/tansm/p/303525.html