简体   繁体   中英

ResolveEventHandler in DLL (class library)

In C# there is ResolveEventHandler event to load external dll s if they are not inside application directory.

To use it in winform application I register the event in Program.cs Main() function like the following:

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);

and then there is the ResolveAssembly function that gets called every time the event is fired:

    static Assembly ResolveAssembly(object sender, ResolveEventArgs args)
    {
        //MessageBox.Show(String.Format("Assembly {0} is missing", args.Name));


        //This handler is called only when the common language runtime tries to bind to the assembly and fails.

        //Retrieve the list of referenced assemblies in an array of AssemblyName.
        Assembly MyAssembly, objExecutingAssemblies;
        string strTempAssmbPath = "";
        string AssemblyName = new AssemblyName(args.Name).Name;

        objExecutingAssemblies = Assembly.GetExecutingAssembly();
        AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();

        //Loop through the array of referenced assembly names.
        foreach (AssemblyName strAssmbName in arrReferencedAssmbNames)
        {
            //Check for the assembly names that have raised the "AssemblyResolve" event.
            if (strAssmbName.Name == AssemblyName)
            {
                //Build the path of the assembly from where it has to be loaded.                
                strTempAssmbPath = @"C:\PowerVision\libraries\" + AssemblyName + ".dll";
                break;
            }

        }
        //Load the assembly from the specified path.                    
        MyAssembly = Assembly.LoadFrom(strTempAssmbPath);

        //Return the loaded assembly.
        return MyAssembly;
    }

The question is how can I add/call this event in/from class library?

I have a class library (DLL) that has 3 references to external DLL s. I don't want to copy these dlls into application directory and don't want to place them into application's subdirectory. These DLLs should stay in a specific external folder (hence using the event).

The problem is I don't know where in DLL(class library) to put this event registration:

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);

You just need to put the event registration in your DLL in a place that gets called sometime BEFORE any of your 3 external DLLs get referenced.

A constructor of an object in your top DLL would be the first place to look. However, if that object is a sub-type of an object that is in one of those 3 external DLLs, then you may need to create a parent object for that object, and call the parent object first, and add the event registration in that parent's constructor.

Eg if your DLL is a UserControl that is based on another UserControl that is in one of those 3 external DLL's, like this:

public partial class TopLevelUserControl: ExternalDllUserControl
{
    InitializeComponent();
}

then you may need to write code like this: Create a new user control called TopLevelUserControlLauncher, and place TopLevelUserControl in that userControl, docked. Then write code like this:

public partial class TopLevelUserControlLauncher: UserControl
{
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);
    InitializeComponent(); // this will construct TopLevelUserControl
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM