Reduce the number of generated dll and the number of generated dll
Before the opening, I want to despise myself. I don't need to write this thing at all. I already have something to implement. As my team lead said, there are too few open-source projects. In fact, this thing can be completely solved by ILMerge.
Then let's talk about the preface. After developing things for a long time, we will always accumulate a certain amount of Helper or Util, so we will compile a dll together in a project, which is convenient to use, but the problem is that Helper like SQLite needs to carry its dll, and then encapsulate several classes, with more dll. Sometimes we want to use a very simple Helper, the results also contain a lot of irrelevant dll files, which will be uncomfortable, and there is a feeling that the reference is simply a Common. dll is enough. What System. data. SQLite. dll, System. data. mySql. I don't want to bring any dll. I am inspired by the stream when I use embedded resources at a time. I will put these dll files into the project resources during compilation and load them as needed, that's all.
This simply applies to the use of embedded resources. The other is the AppDomain's knowledge about dll loading.
When using embedded resources, you need to include the resources in the project. Embedded resources are displayed on the "generate operations" Page and select "sneak into resources ",
You must use the stream to read resources during encoding. You can use the GetManifestResourceStream (string name) method of Assembly to obtain the resource stream, the Code is as follows:
1 Stream s = null; 2 byte[] dllDatas = null; 3 try 4 { 5 s = Assembly.GetExecutingAssembly().GetManifestResourceStream("ConsoleApplication2.ClassLibrary1.dll"); 6 dllDatas = new byte[s.Length]; 7 s.Read(dllDatas, 0, dllDatas.Length); 8 } 9 catch (Exception ex)10 {11 return null;12 }13 finally14 {15 if (s != null)16 {17 s.Close();18 s.Dispose();19 }20 }
When the dll stream gets the stream, the place where it is used is in the AssemblyResolve event of AppDomain. When the application domain loads an external assembly, it will find it in two places by default. The first is.. NET Framework directory, and then find the application in the directory where the application is located. Therefore, by default, the class library we develop will be placed in a directory with the reference program, and the frequently used System. dll does not need to be placed in the referenced program directory. If the required dll cannot be found from these two locations, the program will throw the FileNotFoundException exception, which can still be solved. In fact, before the FileNotFoundException exception is thrown, The AppDomain will first trigger the AssemblyResolve event, this event will return the undefined assembly, and the returned assembly is empty, the FileNotFoundException exception will be thrown, as long as we have registered the AssemblyResolve event, obtain the dll from the resource in the bound method. After the Assembly is loaded, the Assembly that cannot be found in the file directory can be loaded into the program domain. classes in the Assembly can be used as usual.
The Code is as follows:
1 AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 2 3 4 static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 5 { 6 7 Stream s = null; 8 byte[] dllDatas = null; 9 try10 {11 s = Assembly.GetExecutingAssembly().GetManifestResourceStream("ConsoleApplication2.ClassLibrary1.dll");12 dllDatas = new byte[s.Length];13 s.Read(dllDatas, 0, dllDatas.Length);14 }15 catch (Exception ex)16 {17 return null;18 }19 finally20 {21 if (s != null)22 {23 s.Close();24 s.Dispose();25 }26 }27 Assembly assembly= AppDomain.CurrentDomain.Load(dllDatas);28 return assembly;29 }
However, there is a problem. This AssemblyResolve event is suitable for registration in the encapsulated Common project. However, the AssemblyResolve event should be called proactively, and all classes in the Common event should be called, I personally think that this AssemlbyResolve event can be put into the static constructor of the Helper class. In addition, I cannot find a better solution for the moment, or this method is not a good one.
A problem is also found in subsequent development, if this Common. dll is also loaded into the program domain through the AssemblyResolve event in other assembly, these are in the Common. there is a problem with the Assembly loaded by the AssemlbyResolve event in the dll. This issue cannot be explained at the moment. It is estimated that you should learn about CLR.