准备工作:
1. 新建一个控制台程序Project:CombinedDlls.
2. 再新建一个Class Library Project: ThirdPartyTool,新建一个类Util.cs, 在其中实现一个static的SayHelloTo(string name)方法。
3. CombinedDlls引用ThirdPartyTool,并在代码中调用SayHelloTo方法。
SayHelloTo方法。
using System;
namespace ThirdPartyTool
{
public class Util
{
public static void SayHelloTo(string name)
{
Console.WriteLine("Hello " + name);
}
}
}
在控制台程序工程(CombinedDlls)的Main()中调用:SayHelloTo方法。
using System;
using System.Linq;
using System.Reflection;
using ThirdPartyTool;
namespace CombineDlls
{
class Program
{
static void Main(string[] args)
{
Util.SayHelloTo("Peter");
Console.ReadLine();
}
}
}
这时我们Build程序,可是看到Build之后的文件如下图所示。
运行之后如下图所示:
开始改造:
1. 编辑CombineDlls.csproj,在文件中增加以下代码,目的是将引用的dll增加到控制台程序的Resource中。
<Target Name="AfterResolveReferences">
<ItemGroup>
<EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'">
<LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.FileName)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
</EmbeddedResource>
</ItemGroup>
</Target>
增加之后如图所示:
2. 在控制台程序(CombinedDlls)中增加定位在resource中dll的代码,修改完成之后的代码如下:
using System;
using System.Linq;
using System.Reflection;
using ThirdPartyTool;
namespace CombineDlls
{
class Program
{
static Program()
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
static void Main(string[] args)
{
Util.SayHelloTo("Peter");
Console.ReadLine();
}
private static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
var currentAssembly = Assembly.GetExecutingAssembly();
var requiredDllName = $"{(new AssemblyName(args.Name).Name)}.dll";
var resource = currentAssembly.GetManifestResourceNames().Where(s => s.EndsWith(requiredDllName)).FirstOrDefault();
if (resource != null)
{
using (var stream = currentAssembly.GetManifestResourceStream(resource))
{
if (stream == null)
return null;
var block = new byte[stream.Length];
stream.Read(block, 0, block.Length);
return Assembly.Load(block);
}
}
else
{
return null;
}
}
}
}
3. 这时我们Build之后,在output中看到的文件 如下:
我们发现并没有什么不同,我们直接执行结果如下图所示:
我们删掉ThirdPartyTool.dll, ThirdPartyTool.dll.config,ThirdPartyTool.pdb之后,执行结果不变,仍如下图所示:
因为我们已经将ThirdPartyTool.dll添加到CombinedDll.exe中了,因此直接使用CombinedDll.exe即可。