[连载]《C#通讯(串口和网络)框架的统筹及落实》- 9.插件引擎计划

9.1           框架的契约-接口… 2

微博: @表态APP

9.3           实现接口… 4

-投票通知,实时掌握投票比分。

9.3    实现接口

接口和浮泛类都得当“通信契约”,为子类提供标准。下面定义一个接口及抽象类。

//定义一个接口
public interface IMyInterface
{
       void Action(int type);
       string Method(int para);
}

//定义一个抽象类
public abstract class BaseAbstract:IMyInterface

{
       public abstract void Action(int type); //继承此类抽象类时必须实现这个方法。

       public string Method(int para)         //实现这个方法
       {
              return para.ToString();
       }
}

承接口的话,需要贯彻成套概念之不二法门要性质,如下代码:

public class MyClass1:IMyInterface
{
       public void Action(int type)
       {
              Console.WriteLine(type.ToString());
       }

       public string Method(int para)        
       {
              return para.ToString();
       }
}

后续抽象类的语,只需要实现抽象类没有落实之办法要性能,一般为架空方法或者性质,如下代码:

public class MyClass2:BaseAbstract
{
       public void Action(int type)   //继承抽象类,只需要实现这个函数。
       {
              Console.WriteLine(type.ToString());
       }
}

-时事热点,轻点马上与投票

目       录

功能介绍:

9.6    小结

   
下一致段节介绍宿主程序详细计划,需要针对反射机制起自然之问询,并且会使到地方的工具类,并以此基础及展开扩展。

    框架平台将完全了,只需要同粗步了。

 

笔者:唯笑志在

Email:504547114@qq.com

QQ:504547114

.NET开发技术联盟:54256083

文档下载:http://pan.baidu.com/s/1pJ7lZWf

法定网址:http://www.bmpj.net

若果得帮助或取得更多信息,请关注同关系,

9.4    反射机制

   
有矣设施驱动或插件,还不克挂载及框架平台的宿主程序中。我们着想的题材是:已经生矣随机多单门类插件程序集,框架平台如何从程序集中根据类型定义在内存中变化插件对象?

  
回顾普通情况下程序引用其他程序集组件的进程。首先,需要运用“添加引用”对话框加载程序集。然后,通过using关键字引用命名空间。最后,在命令空间下找到相应的近乎,并new出来一个实例。这是平等栽静态加载程序集的艺术。

  
以插件式应用框架中,这种措施并无入。宿主程序于编译时并不知道它将处理哪些程序集,更从未艺术静态的用插件类型通过using关键字引入,这些都是以运行时才能够博取的消息。在这样的景况下,也无法利用静态方法和new关键字来特别成一个路实例。而是用以运转时取得相关消息动态加载程序集,这个进程叫叫做反射。

  
反射是动态发现类型信息的同种植能力,它仿佛后期绑定,帮助开发人员在程序运行时行使程序集信息动态下项目,这些信以编译时是雾里看花之,反射还支持更高级的一言一行,如能以运作时动态创建新类型,并调用这些类别的道等。

   
JIT编译器在拿IL代码编译成本地代码时,会查看IL代码中援引了那些类型。在运行时,JIT编译器利用程序集的TypeRef和AssemblyRef元数据表的笔录项来确定哪一个先后集定义了援的门类。在
AssemblyRef元数据记录项中著录了程序集强名称的依次部分—包括名称,版本,公钥标记和言语文化。这四独片构成了一个字符串标识。JIT编译
器尝试以和这个标识匹配的顺序集加载到手上底AppDomain中。如果程序集是弱命名的,标识中将只包含名称。

   .NET
Framework中,为了实现动态加载,需要熟悉Assembly、Type和Activator等工具类的办法。框架平台要运用了Assembly工具类,这个近乎吃概括Load、LoadFrom和LoadFile。

1.      Assembly的Load方法

  
于里边CLR使用Assembly的Load方法来加载是程序集,这个法与Win32的LoadLibray等价格。在里,Load导致CLR对程序集运一个版重定向策略。并以GAC中寻找程序集,如果没找到,就失应用程序的基目录,私有路径目录及codebase指定的职查找。如果是一个弱命名程序集,Load不会见为程序集应用重定向策略,也不会见失掉GAC中搜寻程序集。如果找到以回来一个Assembly的援,如果没有找到则弃来FileNotFoundException异常。注意:Load方法要既加载一个平等标识的次集才见面简单的回这个次集的援,而非会见错过创造一个新的次序集。

大部动态可扩大应用程序中,Assembly的Load方法是次集加载到AppDomain的首选办法。这种措施欲指定程序集的标识字符串。对于弱命名程序集只用指定一个名字。

2.Assembly的LoadFrom方法

   
当我们明白程序集的路线的场所,可以应用LoadFrom方法,它同意传入一个Path字符串,在中,LoadFrom首先调用AssemblyName的静态方法GetAssemblyName。这个方法打开指定的文件,通过AssemblyRef元数据表提取程序集的标识,然后关文件。随后,LoadFrom在里头调用Assembly的Load方法寻找程序集。到这边,他的所作所为与Load方法是一致的。唯一不同之是,如果依照Load的主意没有找到程序集,LoadFrom会加载Path路径指定的程序集。另外,Path可以是URL。

3.Assembly的LoadFile方法

   
这个措施初一看和LoadFrom方法好像。但LoadFile方法不见面在中调用Assembly的Load方法。它只会加载指定Path的程序集,并且这法子好起随机路径加载程序集,同一程序集而在不同的路下,它同意让频繁加载,等于多只同名的顺序集加载到了AppDomain中,这或多或少暨上面的片单办法了不等同。但是,LoadFile并无会见加载程序集的依靠项,也就算是不会见加载程序集引用的另外程序集,这会招致运行时找不至另外参照DLL的深。要化解之题目,需要往AppDomain的AssemblyResolve事件登记,在回调方法中形加载引用的主次集。类似于如此:

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
       if (args.Name != null)
       {
              return Assembly.LoadFrom(string.Format("{0}\\plugin\\{1}.dll", Application.StartupPath, new AssemblyName(args.Name).Name));
       }
       return null;
}

     
特别注意:要测试LoadFile有没有加载引用的DLL,切不可将DLL拷贝到应用程序的干净目录下测试,因为拖欠目录是CLR加载程序集的默认目录,在斯目录中而在引用的DLL,它会给加载,造成LoadFile会加载引用DLL的假象。可以以干净目录下新建一个子目录如plugin,把援的dll拷贝到立刻其中进行测试。

    
反射机制为发出它的症结:安全性与总体性方面。但是,框架平台在开行的下、以及长新装置驱动(插件)的时段用使用反射,一旦加载到宿主程序中,与静态引用程序集并未本质区别,都是寄在内存中。

邮箱: hi@51biaotai.com

9.5    反射工具类

插件式框架平台利用反射挂载设备驱动,在宿主程序中运作,需要一个专用的家伙类来好相关职能。代码定义如下:

/// <summary>
/// 一个轻便的 IObjectBuilder 实现
/// </summary>
public class TypeCreator : IObjectBuilder
{
       public T BuildUp<T>() where T : new()
       {
              return Activator.CreateInstance<T>();
       }

       public T BuildUp<T>(string typeName)
       {
              return (T)Activator.CreateInstance(Type.GetType(typeName));
       }

       public T BuildUp<T>(object[] args)
       {
              object result = Activator.CreateInstance(typeof(T),args);
              return (T)result;
       }

       /// <summary>
       /// 框架平台主要使用了这个函数。
       /// </summary>
       /// <typeparam name="T"></typeparam>
       /// <param name="assemblyname"></param>
       /// <param name="instancename"></param>
       /// <returns></returns>
       public T BuildUp<T>(string assemblyname, string instancename)
       {
              if (!System.IO.File.Exists(assemblyname))
              {
                     throw new FileNotFoundException(assemblyname + " 不存在");
              }
              System.Reflection.Assembly assmble = System.Reflection.Assembly.LoadFrom (assemblyname);
              object tmpobj = assmble.CreateInstance(instancename);
              return (T)tmpobj;
       }

       public T BuildUp<T>(string typeName, object[] args)
       {
              object result = Activator.CreateInstance(Type.GetType(typeName), args);
              return (T)result;
       }
}

当自身纠结买啊件衣物的时节,我会见就此表态给大家拉自己选择

9.1    框架的契约-接口

    
插件式框架的宿主程序启动后,它首先会见加载相应的配置文件(例如:设备驱动配置文件等),找到呼应的插件程序集,这些程序集以DLL文件格式存在,框架的宿主程序会找到指定的插件类型,由插件引擎依据插件类型(例如:IRunDevice)生成对象实例,由框架的宿主程序的管理器对插件实例进行管制与调度。

   
一个插件程序集可能连多单插件类型,那么框架宿主程序是何许分辨这些品种是否为要加载的插件呢?每个插件对象都出一个地位标识-接口,这个标识在框架设计受到于喻为“通讯契约”。接口可以叫用作是平等种概念了必备之方式、属性与事件的联谊,因此宿主程序就算足以经过这种契约来十分成现实的实例对象,并对另外零件或接口公开只是操作的目标。

   
插件式框架当作一个高聚合低耦合的阳台,它的功能定义和效能实现中是分开的。只要入插件规范之二次开发组件都可挂载到框架平台受到,而它并无并心这些组件的切切实实成效。当然,框架平台提供了片必不可少之信息、机制来保管这些组件能够正常实现二次开发的成效。

   
在拥有多只逻辑层次的结构设计中,各层里的通信大多经过接口来落实,接口不见面随机改变,如果一个重叠的作用发生变化,不会见潜移默化外层;只要正常实现了接口的零部件功能,那么程序的运转就从不问题。这种做法让各层之间的相互影响降低至最低,总之,接口在多工作层级中可知重新好之解耦。

    在大多数功能性的编程和计划性工作着,很少要考虑“接口(interface)
”的气象,如果我们就满足通过控件的法以IDE上编程和使用.NET
Framework中一般的类库,可能永远不见面在次中应用及接口,即使以C#对等面向对象语言的语法书中读者见面多坏看到过之词,也惟有是到位日常的功效,并未掌握面向对象编程的核心思想。

    
接口是相似表现之定义跟契约。如猫及狗等动物,只待用一般性的、公共性的性质、动作等概念在接口里,例如:有眼、可以吃东西顶。尽管不同动物间在好可怜差距,但是接口并无考虑其各自的性状或效益的差别,例如:什么颜色的眼睛、吃啊东西抵。它仅关心这些品种且要贯彻接口定义的所有功能,而落实了之接口就可吃看作是一律栽动物。

    因此,接口的简单个举足轻重的意是:

n  定义多单项目且需要之公物艺术、属性。

n  作为同一栽不可实例化的路是。

持续接口实现定义之不二法门、属性等,实际上是促成了同样栽政策。

庸俗之时光,我会见因此表态来发现新知

第九节           插件引擎设计… 2

表态,一款款实时互动娱乐投票工具,记录你各个一样不成态度的达

 

-发起话题,了解身边人之态势。

9.5           反射工具类… 8

-个人基本,通过各一样软表态,了解真实的温馨。

第九节     插件引擎计划

在介绍《第10回
宿主程序详细规划》之前对接口及插件的有关内容展开一下完完全全介绍,在统筹宿主程序的当儿会为此到这些知识,也是宿主程序及插件之间相互的核心内容。

上班途中我会刷表态,看看身边的人口对新星事件的情态

9.2           插件的雏形-抽象类… 3

本人莫喜投其所好的个性化推荐,我期待用表态来看莫相同的世界

9.6           小结… 9

公众号:表态

9.2    插件的雏形-抽象类

接口和虚幻类非常相像,例如两者都未能够new一个实例对象,却还得以发

呢同一栽契约和概念为应用。但是接口及抽象类闹实质的不等,这些不同包括:

n  接口没有其他实现部分,但是抽象类可继续接口后有些实现代码。

n  接口没有字段,但是抽象类可分包字段。

n  接口可以为组织(Struct)继承,但是抽象类非常。

n  抽象类闹构造函数和析构函数。

n  接口就能够继承自接口,而空虚类可继续自其他类及接口。

n  接口支持多累,抽象类仅支持单根继承。

每当MSDN的连带内容遭,给起了如下关于接口及抽象类的提议:


如果预测要创造组件的差不多个版本,则创造抽象类。抽象类提供简单易行的法子来控制组件版本。通过创新基类,所有继承类都照转自动更新。另一方面,接口一旦创立就未克更改,如果如创新接口的版本,必须创造一个簇新的接口。


如果创建的作用以在特别范围之全异对象中用,则用接口。抽象类应要用于关系密切的目标,而接口最符合啊未系的好像提供通用的效力。


如果要是统筹小而简易的功能模块,应该利用接口。如果要规划好之效应单元,则当运用抽象类。


如果假定于组件的兼具实现中提供通用的已经落实力量,应该采取抽象类。抽象类允许一些实现类似,而接口不含其他成员的兑现。

-发表评论,谈谈您对问题之观。

9.4           反射机制… 5