C # Reflection-assembly.load, LoadFrom and LoadFile advanced

Source: Internet
Author: User

About. NET, there are three common methods:

Assembly.Load ()
Assembly.LoadFrom ()
Assembly.loadfile ()

Let's talk about the difference between these three methods and some details.

1. Assembly.Load () Introduction

The load () method receives a string or assemblyname type as a parameter, which is actually a strong name (name, version, language, public key token) of the assembly that needs to be loaded. For example, the FileIOPermission class in. NET 2.0, whose strong name is:

System.Security.Permissions.FileIOPermission, mscorlib, version=2.0.0.0, Culture=neutral, publickeytoken= b77a5c561934e089

For weakly named assemblies, there is only the assembly name, not the version, the language, and the public key token. such as testclasslibrary

Details
    • The load () method is commonly used internally by the CLR to load an assembly, and within the load () method, the CLR first applies the version-binding redirection policy of the Assembly, and then finds the target assembly in the GAC. If it is not found in the GAC, it looks in the application directory and subdirectories (the location specified by the codebase of the application configuration file).
    • If you want to load a weakly named assembly, the Load () method does not go to the GAC to find it.
    • When load () finds the target assembly, it loads it and returns a reference to the corresponding Assembly object.
    • The System.IO.FileNotFoundException exception is thrown when an assembly is not found.
    • When there is an assembly for a particular CPU architecture, the CLR takes precedence over the assembly of the current schema (for example, the x86 version takes precedence over the Il neutral version)
    • If you want to force a schema version of an assembly to be loaded, you need to specify it in a strong name. processorarchitecture can be x86 IA64 AMD64 or MSIL, and of course None
    • The Load method is equivalent to the LoadLibrary method in the Win32 function

2. Assembly.LoadFrom () Introduction

The LoadFrom () method loads an assembly from the specified file, learns all references and required assemblies by looking up the assembly's AssemblyRef metadata table, and then calls the load () method internally.

Assembly.LoadFrom (@ "C:\ABC\Test.dll");
Details
    • LoadFrom () First opens the assembly file, obtains the assembly name through the GetAssemblyName method, closes the file, and finally passes the resulting AssemblyName object into the load () method
    • The load () method will then open the file again to load. Therefore, when LoadFrom () loads an assembly, it opens the file multiple times, resulting in inefficient behavior (compared to load).
    • Because load () is called internally, the LoadFrom () method also applies a version-binding redirection policy, which is also found in the GAC and in each specified location.
    • LoadFrom () directly returns the result of load ()-a reference to a assembly object.
    • If the target assembly has already been loaded, LoadFrom () does not reload.
    • LoadFrom supports loading assemblies from a URL (such as "Http://www.abc.com/test.dll"), which is downloaded to the user cache folder.
    • When loading an assembly from a URL, LoadFrom throws an exception if the computer is not networked. If IE is set to work offline, no exception is thrown and the downloaded file is looked up from the cache instead.

3. Assembly.loadfile () Introduction

LoadFile () loads an assembly from a specified file, which differs from LoadFrom () in that LoadFile () does not load other assemblies referenced and dependent by the target assembly. You need to control and show that all dependent assemblies are loaded

Details
    • LoadFile () does not resolve any dependencies
    • LoadFile () can load the same assembly multiple times
    • To explicitly load dependent assemblies, register the Assemblyresolve event for the AppDomain

--------------------------------------------------------------------------------------------------------------- ---------------------------

Some of the knowledge about C # Reflection is estimated to be up to the extent of using the API, as far as it is difficult to get a deeper understanding of the current level of estimation, so the following article, as a summary of the phase.

For the summary of reflection, I want to start with a reflection assembly, a module, a member of the class, and some information about the member, and then the member method of the dynamic invocation class, and the third aspect of dynamically generating assemblies, modules and classes, and members of the class. Okay, now let's start by reflecting all sorts of information.

In C #, we want to use reflection, first to understand the relationships of several classes in the following namespaces:

System.Reflection namespaces

(1) AppDomain: An application domain that can be understood as a logical container for a set of assemblies

(2) Assembly: assembly class

(3) Module: Modular class

(4) Type: The most core class for using reflection to get type information

There is a dependency between them, that is, an AppDomain can contain N assembly, a assembly can contain n module, and a module can contain n type.

The AppDomain is a class we'll explain later. Let's focus on assembly classes first.

In the program, what if we want to load an assembly dynamically? There are several ways to use it, namely, load, LoadFrom, and loadwithpartialname three assembly static methods.

To explain the Assembly.Load method, the method will have multiple overloaded versions, one of which is to provide the details of the Assembly, that is, the identity of the Assembly, including the assembly name, version, zone information, public key token, all provided as a string, for example: " myassembly,version=1.0.0.0,culture=zh-cn,publickeytoken=47887f89771bc57f ".

So what is the order of loading assemblies using Assembly.Load? First it goes to the global assembly cache lookup, then to the application's root directory, and finally to the application's private path lookup.

Of course, if you are using a weakly named assembly, which gives you only the name of the assembly, then at this point the CLR will not apply any security or deployment policies on the assembly, and load will not find the assembly in the global cache assembly.

Examples of tests that load weakly named assemblies are as follows:

(1) Create a new console Application project, and check the creation of a solution

(2) Create a new class library project in the solution, write a class and a method casually

(3) In the console project, first do not add a reference, directly in the main method to add the following code:

Assembly Assembly = Assembly.Load ("myassembly");

if (assembly! = null)

{Console.WriteLine ("Load Succeeded");}

Executes the program and throws an exception saying that the assembly could not be found. What's the reason? Because we are using a weakly named assembly, the Load method does not look in the global assembly cache, and the application directory does not have the assembly, so the program cannot find it. At this time, we change the program a little bit, without adding code, just add a reference to MyAssembly, rerun the program, loaded successfully.

Next, we'll look at how load loads the strong-named assembly, which is a little bit more complicated. Or just the project, find the directory where the MyAssembly.dll assembly is located, usually in the bin "debug directory

(1) Generate key pair file Sn–k Myassemblykey.keys

You can do it yourself. A key pair file name

(2) Generate a public key file

Sn–p Myassemblykey.keys Myassemblypublickey.publickey

Note: View public key command: SN–TP Myassemblypublickey.publickey

(3) Create a strong-named assembly.

Simply add the following feature to the code that declares the namespace:

[Assembly:assemblykeyfileattribute (@ "D:" Test "Myassemblykey.keys")]

(4) Compile the project

(5) Add an assembly to the Assembly global cache

Gacutil–i MyAssembly.dll

At this point, go to the project that loads the assembly, change the parameters in the Load method to "assembly name, version= version, culture= zone information, publickeytoken= public key", and then remove the reference to the Assembly, and we will find that the program runs successfully. Indicates that the load has found the assembly in the global cache.

Using the Load method to load assemblies, especially strong-named assemblies, to apply security and deployment policies on assemblies, it is recommended to use this method to load assemblies dynamically, as for LoadFrom and LoadWithPartialName.

First, let's take a look at the LoadFrom method, the principle of which is this: if we want to use it to dynamically load an assembly, we must tell it the path of the Assembly, that is, under which directory the CLR will load an assembly that exactly matches the path you specify. Remember, when we specify the assembly path, we cannot include any information about the strong naming of the assembly, so the CLR does not apply any policy on the assembly file that we specify, and does not go anywhere else to search for the assembly, in short, it refers to where to hit, hehe.

For example: You have an assembly in D:/test/myassembly.dll, you want to load the assembly with Assembly.LoadFrom, the code is as follows:

Assembly Assembly = Assembly.LoadFrom (@ "D:/test/myassembly.dll");

For the Loadwithparitalname method, it is recommended that you do not use it because the program cannot determine which assembly version is ultimately going to be loaded, so here's just a brief introduction to how it works: You can pass an assembly ID to it, including the assembly name, As for other information is optional (area information, public key, etc.), when the method executes, it first checks the qualifyassembly node of the configuration file in the application, and if so, replaces the assembly of that part name with the full assembly identity, if it does not exist, Use the assembly name to look in the application root, then the private directory, and find it in the assembly global cache if it is not found. The simple process is as follows:

Assembly global Cache, application Private directory, application root directory.

the difference between the Assembly.Load () method, the Assembly.LoadFrom () method, the Assembly.loadfile () Method!

1,assembly.load ()

This method loads the assembly through the long name of the assembly (including assembly name, version information, language culture, public key token), loads the other assemblies referenced by this assembly, and generally should take precedence over this method, which is much more efficient than LoadFrom. And does not cause the problem of repeated loading (the reason is explained on the 2nd)

With this method, the CLR applies a certain policy to find the assembly, in effect the CLR locates the Assembly in the following order:

⑴ If the assembly has a strong name, first look for the Assembly in the global Assembly Ease (GAC).

⑵ if the strong name of the assembly is not specified correctly or is not found in the GAC, the URL specified by the <codebase> element in the configuration file is searched for

⑶ If a strong name is not specified or cannot be found in the GAC, the CLR probes for a specific folder:

Assuming that your application directory is a privatepath in the c:\appdir,<probing> element that specifies a path Path1 the assembly you are targeting is AssemblyName.dll, the CLR will locate the assembly in the following order

C:\AppDir\AssemblyName.dll

C:\AppDir\AssemblyName\AssemblyName.dll

C:\AppDir\Path1\AssemblyName.dll

C:\AppDir\Path1\AssemblyName\AssemblyName.dll

If the above method cannot find the assembly, a compilation error occurs, and if the assembly is loaded dynamically, an exception will be thrown at run time!

2,assembly.loadfrom ()

This method loads the assembly from the specified path, and when the method is actually called, the CLR opens the file, gets the assembly version, language culture, public key token, and so on, passes them to the Load method, and then theload method uses the above policy to find the assembly. If an assembly is found, it is compared to the path specified in the LoadFrom method, and if the path is the same, the Assembly is considered part of the application, and if the path is different or the Load method does not find the assembly, the Assembly is simply loaded as a "data file". is not considered part of the application. This is why the load method mentioned in the 1th is more efficient than the LoadFrom method. In addition, because the assembly may be loaded as a "data file", loading the same assembly from different paths with LoadFrom causes a duplicate load. Of course, this method will load other assemblies referenced by this assembly.

3,assembly.loadfile ()

This method loads the assembly from the specified file and differs from the method above in that the method does not load other assemblies referenced by this assembly!

Conclusion: In general, you should choose the Load method to load the assembly, if you encounter the need to use the LoadFrom method, it is best to change the design and use the Load method instead!

Another: The difference between Assembly.loadfile and Assembly.LoadFrom

1, assembly.loadfile only load the corresponding DLL file, such as Assembly.loadfile ("Abc.dll"), then load Abc.dll, if Abc.dll is referenced def.dll, Def.dll will not be loaded.

Assembly.LoadFrom is not the same, it loads the DLL file and other DLLs it references, such as the example above, Def.dll will also be loaded.

2, when loading a assembly with Assembly.LoadFrom, will first check whether the front has been loaded with the same name assembly, such as Abc.dll has two versions (version 1 under directory 1, version 2 is placed under directory 2), the program was initially loaded in version 1, When loading version 2 o'clock with Assembly.LoadFrom ("2\\abc.dll"), it cannot be loaded, but instead returns version 1. Assembly.loadfile will not do such a check, such as the above example to Assembly.loadfile, then the correct loading version 2.

LoadFile: Loads the contents of the assembly file on the specified path. LoadFrom: Loads the contents of the assembly file based on the file name of the assembly.

Difference:

The LoadFile method is used to load and check assemblies that have the same identity but are located in different paths. But the program's dependencies are not loaded.

LoadFrom cannot be used to load an assembly that identifies the same but has a different path.

C # Reflection-assembly.load, LoadFrom and LoadFile advanced

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.