在开篇之前我想鄙视我自己一下,这个东西根本不需要去写,本来已经有东西去实现了,正如我组长说我的,看的开源项目太少了。其实这个东西完全可以用ILMerge来解决。

  然后再说说前言,开发东西久了,总会积累到一定量的Helper或Util,于是都放到一个项目里面一起编一个dll,用的时候就方便,可是问题来了,像SQLite这种Helper需要带上它的dll,再多封装几个类,附带的dll就更多了,有时候想单单用一个很简单的Helper,结果还带了一大堆不相干的dll,会不爽,而且有种感觉是引用时就单纯一个Common.dll就够了,什么System.Data.SQLite.dll,System.Data.MySql.dll我都不想带,在一次使用内嵌资源时给流我灵感,把这堆dll在编译的时候都放到项目资源中,需要的时候就去加载,这样就行了。

  单纯这个就用到了内嵌资源使用方面的知识,另外一个就是AppDomain对dll加载方面的知识。

  在使用内嵌资源时,要把资源包含在项目里面,内嵌的资源在属性页面上"生成操作"选择"潜入资源",

  在编码时要把资源用上,得用流来读取,通过Assembly的GetManifestResourceStream(string name);方法就可以把资源的流获取到,流到了就爱干嘛干嘛,代码如下

             Stream s = null;
byte[] dllDatas = null;
try
{
s = Assembly.GetExecutingAssembly().GetManifestResourceStream("ConsoleApplication2.ClassLibrary1.dll");
dllDatas = new byte[s.Length];
s.Read(dllDatas, , dllDatas.Length);
}
catch (Exception ex)
{
return null;
}
finally
{
if (s != null)
{
s.Close();
s.Dispose();
}
}

dll的流拿到流,使用它的地方就在AppDomain的AssemblyResolve事件,当应用程序域加载外部的程序集时,它会默认往两个地方找,第一是往.NET Framework的目录中找,再到应用程序所在目录中找,所以在默认情况下我们开发的类库都会跟引用程序放到一个目录,而经常用到的System.dll才不需要放到引用程序目录中。那假如需要的dll没办法从这两个地方找到的话,程序会抛出FileNotFoundException异常,这个仍然有办法解决的,其实在抛出FileNotFoundException异常之前,AppDomain会先触发AssemblyResolve事件,这个事件会返回这个无法找到的程序集,返回的程序集为空,才会抛FileNotFoundException异常,只要我们注册了AssemblyResolve事件,在绑定的方法中把dll从资源中取出来,加载上程序集之后,无法在文件目录中找到的程序集就可以加载到程序域中,程序集中的类可以照常使用

代码如下

 AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

         static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{ Stream s = null;
byte[] dllDatas = null;
try
{
s = Assembly.GetExecutingAssembly().GetManifestResourceStream("ConsoleApplication2.ClassLibrary1.dll");
dllDatas = new byte[s.Length];
s.Read(dllDatas, , dllDatas.Length);
}
catch (Exception ex)
{
return null;
}
finally
{
if (s != null)
{
s.Close();
s.Dispose();
}
}
Assembly assembly= AppDomain.CurrentDomain.Load(dllDatas);
return assembly;
}

  但是存在一个问题,这个AssemblyResolve事件在封装的Common项目中注册比较合适,可是AssemblyResolve事件应该是主动调用的,而Common里面的类全都是被调用的,个人觉得这个AssemlbyResolve事件可以放到Helper类的静态构造函数里面,此外也暂时想不出更好办法,或者这种方式本身不是一个好的方式。

  后续在开发中也发现一个问题,假如这个Common.dll在别的程序集也是通过AssemblyResolve事件被加载到程序域中的时候,这些在Common.dll里面通过AssemlbyResolve事件加载进来的程序集有问题。此问题还暂时无法解释,估计要学习一下CLR方面的知识。

减少生成的dll数量的更多相关文章

  1. 使用python创建生成动态链接库dll

    如今,随着深度学习的发展,python已经成为了深度学习研究中第一语言.绝大部分的深度学习工具包都有python的版本,很多重要算法都有python版本的实现.为了将这些算法应用到具体工程中,这些工具 ...

  2. 生成解决方案,主项目的bin目录下没有其他项目生成的dll

    问题说明: 我的项目组成: 主项目为:TaskUtlity 在生成解决方案的时候在TaskUtlity的bin目录下老是找不到ProBonus项目生成的dll. 解决方案: 1.打开sln文件,找到P ...

  3. VS2008 C++ 调用MATLAB 2009b 生成的DLL .

    转载: 刚开始学习用VC++调用matlab生成的DLL,找了网上一些资料,难以找到vs2008与MATLAB2009b版本的,按照以往版本做的总是有很多错误.经过两天努力,终于调试成功,这里将经验总 ...

  4. c++调用matlab生成的Dll动态连接库

    点击打开链接http://download.csdn.net/detail/nuptboyzhb/4228429 c++调用matlab生成的Dll动态连接库 实验平台:   matlab 7.0(R ...

  5. C++调用C#生成的DLL文件的各种问题

    C++调用C#生成的DLL文件: 首先选择建立一个C#的类库,然后再按照需求编写需要的函数 之后,对于C++调用过程需要注意的几点: 1.使用#using <....some.dll>指出 ...

  6. MinGW gcc 生成动态链接库 dll 的一些问题汇总 (补充)

    我以前写过一个小短文,介绍MinGW gcc 生成动态链接库 dll 的一些问题.当时写的并不全面.近期又遇到写新的问题.这里记录一下,做个补充. 通常情况下,dll 中的函数假设採用 _stdcal ...

  7. 在VS2010上使用C#调用非托管C++生成的DLL文件

    背景 在项目过程中,有时候你需要调用非C#编写的DLL文件,尤其在使用一些第三方通讯组件的时候,通过C#来开发应用软件时,就需要利用DllImport特性进行方法调用.本篇文章将引导你快速理解这个调用 ...

  8. VC生成的DLL给QT的EXE调用时lib路径问题小结

    VC生成的DLL给QT调用,有两种方式,一种是隐式调用调用(使用.lib文件方式): ① 在*.pro工程文件中添加VC生成的lib文件路径时,或者使用一个绝对路径,如: LIBS += " ...

  9. VS2012环境下C#调用C++生成的DLL

    1.VS2012 C++生成DLL 这个过程仿照http://www.cnblogs.com/LCCRNblog/p/3625200.html创建DLL即可,暂时不用创建测试工程,因为下面有测试工程的 ...

随机推荐

  1. .NET面试题系列[0] - 写在前面

    .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] - .NET框架基础知识(2) .NET面试题系列[3] - C# 基础知识(1) .NET ...

  2. Linux sudo

    200 ? "200px" : this.width)!important;} --> 介绍 本篇文章主要介绍sudo配置和用法,为了给某个用户控制权限比如执行某个命令或者关 ...

  3. 当程序以Windows Services形式启动时当前路径不对

    当程序以Windows Services形式启动时当前路径不对 @(操作系统)[博客|dotNet] 很多时候我们需要将我们的程序写成利用Windows服务的形式来让它能够自启动.今天遇到一个问题,当 ...

  4. [Unity3D]自己动手重制坦克舰队ArmadaTank(2)从碰撞说起

    [Unity3D]自己动手重制坦克舰队ArmadaTank(2)从碰撞说起 在上一篇里我给出了重制的坦克舰队效果图和试玩程序.本篇介绍一下玩家坦克和敌方坦克碰撞问题. +BIT祝威+悄悄在此留下版了个 ...

  5. ASP.NET MVC 从零开始 - 自动化部署(其一)

    本文是从我的 github 博客 http://lxconan.github.io 导入的. 这是这个系列的第四篇了,前三篇请参见: ASP.NET MVC 从零开始 – Create and Run ...

  6. fc-san

    在SAN网络中,所有的数据传输在高速.高带宽的网络中进行,SAN存储实现的是直接对物理硬件的块级存储访问,提高了存储的性能和升级能力. 早期的SAN采用的是光纤通道(FC,Fibre Channel) ...

  7. UIColor 使用起来的坑

    我们一般会用 UIColor 的RGB来生成颜色: [UIColor colorWithRed:220/255 green:220/255 blue:220/255 alpha:1.0];//这样生成 ...

  8. web应用中使用JavaMail发送邮件

    现在很多的网站都提供有用户注册功能, 通常我们注册成功之后就会收到一封来自注册网站的邮件.邮件里面的内容可能包含了我们的注册的用户名和密码以及一个激活账户的超链接等信息.今天我们也来实现一个这样的功能 ...

  9. 我也来说说DDD~大话目录

    回到占占推荐博客索引 DDD之前没有接触过,但一但有了接触就一发不可收拾,他会带去进入一个全新的世界! DDD不是新技术,而是新思想,新模式,是软件开发领域的一次突破,它更接近于业务,对于业务的改动它 ...

  10. OpenGL学习进程(13)第十课:基本图形的底层实现及算法原理

        本节介绍OpenGL中绘制直线.圆.椭圆,多边形的算法原理.     (1)绘制任意方向(任意斜率)的直线: 1)中点画线法: 中点画线法的算法原理不做介绍,但这里用到最基本的画0<=k ...