We know that reflection is the basis of a dependency injection pattern, and dependency injection requires that only the assembly that defines the interface be referenced in the project, not the assembly of the interface implementation class, because the assembly of the interface implementation class should be dynamically loaded through reflection to ensure loose coupling between the interface and its implementation class. But sometimes we fail when we use reflection to dynamically load an assembly, because unless we manually place the assembly of the interface implementation class in the bin directory after the project is built, or in the GAC, the. Net framework does not know where to look for the DLL assembly file for the interface implementation class. Fortunately, if we use the AppDomain.CurrentDomain.AssemblyResolve event, we can customize the assembly load logic through C # code, and when C # reflects the parsing assembly failure, Locate the appropriate assembly DLL file by executing the custom assembly load logic.
For example, we now define a common C # class library project called Messagedisplay, as shown in
It contains only a C # class MessageDisplayHelper.cs file, the MessageDisplayHelper.cs code is as follows:
using System; namespace messagedisplay{ publicclass messagedisplayhelper { public string Display () { return'This isa message! " ; } }}
Then we define a C # console program called Assemblyresolverconsle:
Instead of referencing the Messagedisplay assembly directly in this console program, we use reflection to load the assembly Messagedisplay and then dynamically construct the Messagedisplayhelper class using reflection. Since we did not directly refer to the Messagedisplay assembly in the console program Assemblyresolverconsle, Therefore, when the Assembly.Load method is called to dynamically load the assembly, it fails, triggering the AppDomain.CurrentDomain.AssemblyResolve event. The Program.cs file code for the Assemblyresolverconsle console program is as follows:
usingSystem;usingSystem.Reflection;namespaceassemblyresolverconsle{classProgram {Static voidMain (string[] args) { //The assemblyresolve event is triggered when the assembly fails through reflection loading, where the handler for registering the Assemblyresolve event is Currentdomain_assemblyresolveAppDomain.CurrentDomain.AssemblyResolve + =Currentdomain_assemblyresolve; //the loading of the Messagedisplay assembly fails by calling the Assembly.Load method, because the assembly is not referenced in this project, and the DLL file for the Messagedisplay assembly is not in the bin directory generated by this project, nor in the GAC. So this will trigger the Assemblyresolve event, call the handler Currentdomain_assemblyresolve to try to execute the custom assembly load logic, and then handle the function Currentdomain_ Assemblyresolve will return the MessageDisplay.dll assembly for the Assembly.Load method here varmessagedisplayassembly = Assembly.Load ("Messagedisplay"); //using reflection to dynamically invoke the constructor of the Messagedisplayhelper class varMessagedisplayhelper = Messagedisplayassembly.createinstance ("Messagedisplay.messagedisplayhelper"); Console.WriteLine (Messagedisplayhelper.tostring ()); Console.ReadLine (); } /// <summary> ///The handler function for the Assemblyresolve event, which loads the logic with a custom assembly/// </summary> /// <param name= "Sender" >Event-Raising source</param> /// <param name= "args" >event arguments, from which you can get the name of the assembly that failed to load</param> /// <returns></returns> Private StaticSystem.Reflection.Assembly Currentdomain_assemblyresolve (Objectsender, Resolveeventargs args) { //finds the assembly based on the name of the load failed assembly and returns if(args. Name = ="Messagedisplay") { //Our custom assembly loading logic knows that the Messagedisplay assembly is in C:\AssemblyResolverConsle\Reference\ MessageDisplay.dll this path, so here load the DLL file under this path as the return value of the Assemblyresolve event handler function returnAssembly.loadfile (@"C:\AssemblyResolverConsle\Reference\MessageDisplay.dll"); } //if the handler for the Assemblyresolve event returns NULL, indicating that the handler for the Assemblyresolve event cannot find the assembly that failed to load, the entire program throws an exception error return NULL; } }}
So AppDomain.CurrentDomain.AssemblyResolve This event provides a good solution to the reflection loading assembly failure, allowing developers to customize Assembly parsing logic. We no longer need to put one. NET program requires all the DLL files required to be placed in the bin directory or the GAC, but can be placed in any location, through the AppDomain.CurrentDomain.AssemblyResolve event handler function to dynamically load.
Dynamic parsing of failed assemblies by using the C # assemblyresolve event