介绍

这是本人毕业设计的项目,一直想将其整理成文,可一不小心4年就过去了(这个时间又可以读个大学了)。现在给自己定一个目标,一个月时间里将项目的所有关键点都整理出来。不然真怕一眨眼又一个4年过去了,而代码依然躺在硬盘里。

项目取名MathAssist,使用vs2008。分成四个子项目:

  1. MathAssistLibrary    提供一个接口,以便实现用dll拓展的插件机制
  2. SuperCalculator   实现任意大数计算的插件
  3. 命令证明              实现简单逻辑命题证明的插件
  4. MathAssist          主程序,会扫描并加载其路径下所有符合条件的dll

其主程序可以从插件中扫描可用的命令,也可以显示插件中可用的窗体。如下是主程序界面,其加载了两个插件:“superCalculator”和“命令证明”。它们分别提供命令cal prove。

点击菜单项"插件"的子菜单后可以分别打开两个插件中实现的窗口。如下图

分别实现了大数计算和逻辑命题的证明。

在这篇前言中就先只介绍插件机制的实现吧,大数计算和逻辑命题的证明就留给后面的系列。

插件机制的实现

MathAssistLibrary接口的定义

在MathAssistLibrary项目中只定义了两个接口: ICommand, IForm,分别用于提供命令行功能和窗口功能。

     /// <summary>命令接口</summary>
public interface ICommand
{
/// <summary>命令名称</summary>
string Name { get; } /// <summary>执行命令</summary>
/// <param name="cmd">命令参数</param>
/// <returns>返回的结果</returns>
string Excute( string cmd ); /// <summary>对命令的使用作相应的说明</summary>
string Describe { get; }
}
/// <summary>获得插件的窗体</summary>
public interface IForm
{
/// <summary>窗体名</summary>
string Text { get; } /// <summary>窗体对象</summary>
Form GetForm { get; }
}

MathAssistLibrary

ICommand接口

  • Name 用于表示命令的名称
  • Excute 用于执行命令
  • Describe 用于对这个命令提供一个简要的帮助文档说明

IForm接口

  • Text 用于表示窗体的名称
  • GetForm 用于获取Form对象。在主程序中获取Form对象后,再调用Show()即可显示之。

插件实现

在插件项目中只要实现ICommand和IForm两个接口即可,以SuperCalculator为例:

public partial class frmSuperCalculator : Form, IForm
{
string IForm.Text {
get { return "计算器"; }
} frmSuperCalculator frm;
Form IForm.GetForm {
get {
if (frm == null || frm.IsDisposed) {
frm = new frmSuperCalculator();
}
return frm;
}
}
...
}
public class Calculator : MathAssistLibrary.ICommand
{
string MathAssistLibrary.ICommand.Describe {
get { return "cal命令可以进行相关的数学运算。比如cal 1+max(2,3)*2"; }
}
string MathAssistLibrary.ICommand.Name {
get { return "cal"; }
}
string MathAssistLibrary.ICommand.Excute(string cmd) {
try {
Expression exp = new Expression();
exp.Format = cmd;
return exp.Calculator().ToString();
} catch (ExpressionException e) {
return string.Format("表达式出错。出错类型:{0},出错位置{1}", e.Message, e.Index);
}
}
}

主程序对插件的扫描

FindDllFile()函数找到与程序同路径下的所有dll文件,代码如下:

         List<string> FindDllFile(string foldername) {
DirectoryInfo dir = new DirectoryInfo(foldername);
FileInfo[] files = dir.GetFiles();
List<string> result = new List<string>(); foreach (FileInfo fi in files) {
if (fi.Name.ToUpper().EndsWith(".DLL"))
result.Add(fi.FullName);
}
return result;
}

FindDllFile

LoadOne()从一个文件中找一个特定的类型,并返回其对象,代码如下:

        private List<object> LoadOne(string filename, Type type) {
List<object> result = new List<object>(); try {
Assembly ass = Assembly.LoadFrom(filename);
Module[] mods = ass.GetModules(); foreach (Module mod in mods) {
Type[] typs = mod.GetTypes(); foreach (Type typ in typs) {
if (type.IsAssignableFrom(typ)) {
result.Add(ass.CreateInstance(typ.FullName));
}
}
}
} catch (BadImageFormatException) { }
return result;
} // end func

先用Assembly.LoadFrom()加载程序集,然后获取所有模块,最后在所有模块中用type.IsAssignableFrom()找与传入参数type相匹配的类型,如果匹配那么就创建一个对象并返回。

在主程序中分别用如下两行代码调用LoadOne()

List<object> cmd = LoadOne(filename, typeof(ICommand));
List<object> frm = LoadOne(filename, typeof(IForm));

这样用cmd.Excute()就可以执行插件中实现的代码,用frm.Show()就可以显示插件中所实现的窗体。

现提供MathAssist.exe的下载路径。在后面的文章中会给出整个程序的源码,敬请期待~~

参数文献:  http://www.cnblogs.com/conexpress/archive/2009/03/04/MyCalculator_01.html

C#实现任意大数的计算和简单逻辑命题的证明——前言的更多相关文章

  1. boost计算随机数和计算crc32简单示例 - jwybobo2007的专栏 - 博客频道 - CSDN.NET

    boost计算随机数和计算crc32简单示例 - jwybobo2007的专栏 - 博客频道 - CSDN.NET     boost::crc_32_type crc32;       crc32. ...

  2. boost计算随机数和计算crc32简单示例

    boost计算随机数和计算crc32简单示例 - jwybobo2007的专栏 - 博客频道 - CSDN.NET boost计算随机数和计算crc32简单示例 2013-02-18 17:14 10 ...

  3. C++算法之大数加法计算的代码

    如下代码段是关于C++算法之大数加法计算的代码,希望对大家有用. { int length; int index; int smaller; int prefix = 0; if(NULL == sr ...

  4. JQuery插件让图片旋转任意角度且代码极其简单 - 摘自网友

    JQuery插件让图片旋转任意角度且代码极其简单 2012-04-01 09:57:03     我来说两句      收藏    我要投稿 引入下方的jquery.rotate.js文件,然后通过$ ...

  5. ASP.NET中登录功能的简单逻辑设计

     ASP.NET中登录功能的简单逻辑设计                               概述                               逻辑设计             ...

  6. Android计算器简单逻辑实现

    Android计算器简单逻辑实现 引言: 我的android计算器的实现方式是:按钮输入一次,就处理一次. 但是如果你学过数据结构(栈),就可以使用表达式解析(前缀,后缀)处理. 而这个方式已经很成熟 ...

  7. Scrapy爬取小说简单逻辑

    Scrapy爬取小说简单逻辑 一 准备工作 1)安装Python 2)安装PIP 3)安装scrapy 4)安装pywin32 5)安装VCForPython27.exe ........... 具体 ...

  8. python的一个表达式的计算(超简单)

    运行的过程如下: 输入计算表达式:3+5 计算结果:8 然后再次显示计算表达式,等待输入完成后,再次显示结果,依此循环.   作为初学者再适合不过,代码也简单,如下所示: #!/usr/bin/env ...

  9. MDX Cookbook 12 - 计算 SMA 简单移动平均 LastPeriods() 函数的使用

    先认识一下这几个名词 Moving Average (MA) 移动平均,或者叫做移动平均线,是技术分析中一种分析时间序列数据的工具.最常见的就是利用股价,回报或交易量等变数计算出移动平均.可以利用移动 ...

随机推荐

  1. js字符拼接

    for (var j = 0; j < 9; j++) { eval("if (datas[i].b" + j + " == '1') { b[j-1] = 1; ...

  2. 如何快速在当前目录打开cmd命令提示符

    对于稍微熟悉电脑一些的朋友来说.cmd绝对是个很方便的东西.但是每次使用cmd都要cd半天才能到当前目录.怎么快速打开当前目录呢? 当前目录按住shift再右键.然后会看到右键菜单里有一个" ...

  3. RSS阅读器python实现概述

    这边简单说一下最近倒腾的RSS阅读器的小东东,RSS阅读器估计很多人用过或者自己动手实现过.首先wudagang0123多年前提供的一个示例:http://bbs.chinaunix.net/foru ...

  4. 【Python】实现简单循环

    # -*- coding:utf-8 -*- #猜数字游戏 lucky_num = 6 count = 0 while count < 3: input_num = int(raw_input( ...

  5. ECMAScript6 中 类的封装与继承

    ECMASCRIPT6中实现了class关键字,这样使我们更容易也更形象的进行类的操作 <script type="text/javascript"> class OF ...

  6. mac上使用imagealpha命令对图片进行压缩批处理

    #! /bin/bash #BASE_DIR="/Users/jiading/Documents/basepng"; #OUTPUT_DIR="/Users/jiadin ...

  7. ThinkPHP 3.2 获取页面运行时间

    在ThinkPHP中,可以通过在config.php中配置'SHOW_PAGE_TRACE' =>true,打开页面调试,实现页面载入时间的显示.但显示在页面右下角TP的LOGO显然不能适用于我 ...

  8. 基于Maven site的穷人的本地知识管理系统

    1 Motivation On daily study or development, a simple knowledge management system is required. In the ...

  9. 2.4G无线射频通信模块nRF24L01+开发笔记(基于MSP430RF6989与STM32f0308)(1.(2)有错误,详见更正)

    根据网上的nRF24L01+例程和TI提供的MSP430RF6989的硬件SPI总线例程编写程序,对硬件MSP-EXP430RF6989 Launch Pad+nRF24L01P射频模块(淘宝购买)进 ...

  10. 一次 surface pro 3 的售后保修 黑色三月维权(HSD)

    已更新结束....原创 半根毛线 博文原址 http://www.cnblogs.com/hsd-/ 发现大量转载 转载请与作者联系 drizzle1996@outlook.com或注明转载 ---- ...