AssemblyResolveイベント

.netのアセンブリロードのパスはexeのパスかGACかcodeBaseに指定したパスか、のみ。
codeBaseに書くときプライベートアセンブリだとexeのパス以下のフォルダを指定しなければならない。全てのアセンブリをsnすれば配置場所制限はなくなるがpfxの管理が面倒。だからAssemblyResolveイベントを拾って指定パスからロードしようと思った。

コードは簡単。以下のdelegateを作成し

        public Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
        {
            string AssemblyFolder = @"c:\hoge";
            //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 = "";

            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.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(",")))
                {
                    //Build the path of the assembly from where it has to be loaded.				
                    strTempAssmbPath = System.IO.Path.Combine(AssemblyFolder, args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll");
                    break;
                }

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

            //Return the loaded assembly.
            return MyAssembly;
        }

スタートアップでAssemblyResolveイベントにサブスクライブする。

    domain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);

便利だ。オーバーヘッドもたいしてない。よし、これをクラスライブラリdllにしよう。



















それで、そのクラスライブラリはどこからロードするんだ?



orz