Review the Assembly Loading Process under. NET,. netassembly

Source: Internet
Author: User

Review the Assembly Loading Process under. NET,. netassembly

Recently, an old question about. NET is involved in the Assembly loading process. Although many articles on the Internet introduce this part of content, many articles have appeared a long time ago, but after reading the articles, I found that they did not solve my problem, and some points were not particularly detailed, after reading it, I feel like the cloud is still in the fog. Finally, I decided to review this classic and old question and summarize the result. Then, I will have an example to demonstrate this question, hoping to help you.

Assembly Loading Process under. NET

The main step for loading an Assembly under. NET is to determine the Assembly version. In. under. NET, both the hosted DLL and EXE are called Assembly. Assembly is uniquely identified by AssemblyName. AssemblyName is the Assembly that everyone is familiar. fullName is composed of five parts: name, version, language, Public Key Token, and processor architecture. We all know this. For a detailed description of Assembly Name, see https://docs.microsoft.com/en-us/dotnet/framework/app-domains/assembly-names. The version is an important component of AssemblyName. The other four parts are the same. Different versions cannot be regarded as the same Assembly. Microsoft designed such an Assembly version policy to solve the initial DLL Hell problem. On Wikipedia, a detailed description of this section of the Black history is provided at: https://en.wikipedia.org/wiki/dll_hell.

Redirection and final determination of the Assembly version

The Assembly Loading Process under. NET is also the process of determining the Assembly version and locating the Assembly file. The steps are as follows:

So far, the final version of Assembly has been determined, and the next step is to search and load the Assembly file.

Assembly file search and loading process

Now, CLR has started to load the final version of Assembly, and the next step is to search for the Assembly file. This process is also called Assembly Probing. CLR will do the following:

  • Then, CLR explores the root directory and related sub-directories of the application domain:
  • Assume that abc. dll has language settings (not neutral), the CLR will explore the following directory:
  • If an Assembly that matches the version is found, load the Assembly; otherwise, proceed to the next step.
  • Finally, the CLR checks whether the <probling> node exists in the application configuration file. If yes, the value is based on the privatePath value specified by the probling node.Explore one by one. This process will also consider the culture factor, similar to the above step, to search for the corresponding sub-directories. If the corresponding Assembly is found, it is loaded. Otherwise, a FileLoadException is thrown, and the entire loading process ends. Note: The process of "exploring one by one" here is not the process of traversing and finding the best match. CLR only searches for the Assembly file under privatePath Based on the Assembly name (without the version number). If the first name matches but the version does not match, it throws an exception and stops loading, it does not continue searching for other paths in the remainder of privatePath.
  • When the Assembly file fails to be loaded, AppDomain will trigger the AssemblyResolve event. In the subscription function of this event, the customer program can customize the processing method of the failed Assembly, for example, you can use Assembly. loadFrom or Assembly. loadFile calls "manually" to load the Assembly to the AppDomain.

    Bind fuslogvw Assembly to Log Viewer

    A fuslogvw.exe application is included in. NET sdk. it allows you to view detailed Assembly loading processes. The method is simple. Start Visual Studio 2017 Developer Command promptas as an administrator, and then input fuslogvw.exe in the Command line to start the log viewer. After the startup, click the Settings button to enable the logging function:

    After the log is started, click Refresh and start your. NET application. Then you can see the loading process log of the Assembly that the current application depends on:

    Next, I will create an example program and use this tool to analyze the Assembly loading process.

    Implementation of plug-in System and Analysis of Assembly Loading Process

    It combines theory with practice to see how to interpret the Assembly loading process described above through actual code. A good example is to design a simple plug-in system and observe the process of loading the plug-in to understand the ins and outs of Assembly loading. To be simple and intuitive, I call this plug-in system PluginDemo. This plug-in is very simple. The main program is a console application. Then we implement two plug-ins: Earth and Mars. In the Initialize method of different plug-ins, different strings are output.

    The project structure of the entire application is as follows:

    The plug-in system contains four C # projects:

    • PluginDemo. Common: it defines the AddIn abstract class. All plug-in implementations must inherit from this abstract class. In addition, the AddInDefinition class is a class used to save the Metadata plug-in. For demonstration, the Metadata of the plug-in only contains the Assembly Qualified Name of the plug-in type.
    • PluginDemo. App: the application of the plug-in system. When this program is executed, it will scan the DLL in the Modules directory under the program directory, load the corresponding plug-in object according to the Metadata information of module. xml, and execute the Initialize method.
    • PluginDemo. Plugins. Earth: One of the plug-ins is implemented.
    • PluginDemo. Plugins. Mars: Another plug-in implementation

    Note: All the other three projects except PluginDemo. Common have references to PluginDemo. Common. The PluginDemo. App project only depends on PluginDemo. Plugins. Earth and PluginDemo. Plugins. Mars in the project itself. It will not reference these two projects. The purpose is to compile and output the other two plug-in projects to the specified position when PluginDemo. App is compiled.

    In the CustomAddIn class of the Earth plug-in, we implement the Initialize method and output a string here:

    public class CustomAddIn : AddIn{    public override string Name => "Earth AddIn";    public override void Initialize()    {        Console.WriteLine("Earth Plugin initialized.");    }}

    In the Mars maddin class of the Mars plug-in, we also implemented the Initialize method and output a string here:

    public class CustomAddIn : AddIn{    public override string Name => "Mars AddIn";    public override void Initialize()    {        Console.WriteLine("Mars AddIn initialized.");    }}

    In the main program of the plug-in system, module under the Modules subdirectory is scanned. xml file, and then parse each module. the xml file obtains the Assembly Qualified Name of each plug-in class, and then uses the Type. the GetType method obtains the plug-in class, creates an instance, and calls the Initialize method. The Code is as follows:

    static void Main(){    var directory = new DirectoryInfo("Modules");    foreach(var file in directory.EnumerateFiles("module.xml", SearchOption.AllDirectories))    {        var addinDefinition = AddInDefinition.ReadFromFile(file.FullName);        var addInType = Type.GetType(addinDefinition.FullName);        var addIn = (AddIn)Activator.CreateInstance(addInType);        Console.WriteLine($"{addIn.Id} - {addIn.Name}");        addIn.Initialize();    }}

    Next, modify the App. config file:

    <?xml version="1.0" encoding="utf-8" ?><configuration>  <runtime>    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">      <probing privatePath="Modules\Earth;Modules\Mars;" />    </assemblyBinding>  </runtime></configuration>

    In this case, run the program and you will get:

    There is no problem at present. Next, make some changes to the two AddIn. Make these two AddIn dependent on different versions of Newtonsoft. json. For example, Earth depends on 7.0.0.0, Mars depends on 6.0.0.0, and then two Initialize methods of madmaddin are modified, each of which calls JsonConvert. serializeObject method to trigger Newtonsoft. json Assembly loading. Run the program again and you will see the following exception:

    Now, refresh fuslogvw.exe and find the Newtonsoft. Json log:

    Double-click log to view the following information:

    The whole process shows that:

    Then, change the App. config file and change the two values under privatePath to another location?

    Try again:

    At this time, Earth AddIn has an error. Add the version redirection configuration to redirect the program to version 6.0.0.0 when it needs to load Newtonsoft. Json of version 7.0.0.0:

    Execute again, succeeded:

    Check the log:

    The version has been redirected to 6.0.0.0, and Newtonsoft. Json of 6.0.0.0 is found in the Mars directory. The load is successful.

    The source code of this case can beClick here to download.

    Summary

    This article describes in detail the Assembly version determination and loading process under. NET, and provides an example to demonstrate this process.

    Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.