Assembly Loading across AppDomains {2}

本文介绍了一种使用C#实现动态加载程序集到独立AppDomain的方法。通过创建新的AppDomain并加载特定程序集来隔离运行时环境,确保主程序不受影响。文章详细展示了如何配置AppDomain、复制必要的DLL文件,并通过接口实例调用远程方法。
ContractedBlock.gifExpandedBlockStart.gifCode
public class Manager {
        
//private const string CONFIG_ASSEMBLY_POOL =FilePathConstant.APIGenerationDLLTemp;// @"C:\BlogProjects\AssemblyPool";
        private static readonly string privateBinPath;
        
private const string CONFIG_DYNAMIC_ASSEMBLY_PROJECT = "DisconnectedWorker";
        
private const string CONFIG_DYNAMIC_ASSEMBLY_FULLY_QUALIFIED_NAME = "DisconnectedWorker.Worker";

        
private const string FORMAT_WORKER_DOMAIN_FRIENDLY_NAME = "Dynamic Worker Domain";
        

        
static Manager() {
            privateBinPath 
= FilePathConstant.APIGenerationDLLTemp;
        }


        
private void CopyThirdDllToCurrentDomainFolder() {
            FileHelper.CopyCurrentDomainDlls();
            FileHelper.CopyFeaturetteDLLSToTmpFolder(GameProjectHelper.GetGameProjectLocation());
            FileHelper.CopyCssToRunTimeFolder();
        }

        
public void RunAppDomainWorker() {

            CopyThirdDllToCurrentDomainFolder();
            
// create display name for appDomain
            string workerName = string.Format(FORMAT_WORKER_DOMAIN_FRIENDLY_NAME);

            
// Construct and setup appDomain settings:
            AppDomainSetup ads = new AppDomainSetup();

            ads.ApplicationBase 
= FilePathConstant.CONFIG_ASSEMBLY_POOL;

            
//属性值
            
//类型:System..::.String
            
//包含目录名称列表的 String,其中每个名称都用分号隔开。
            
//专用程序集与应用程序部署在同一目录结构中。如果为 PrivateBinPath 指定的目录不在 ApplicationBase 下,它们将被忽略。
            ads.PrivateBinPath = privateBinPath;
            
//ads.PrivateBinPathProbe = "将此属性设置为任何非空字符串可将应用程序的目录路径(即 ApplicationBase)从应用程序的搜索路径中排除,只搜索 PrivateBinPath。";
            ads.DisallowBindingRedirects = false;
            ads.DisallowCodeDownload 
= true;

            ads.ConfigurationFile 
= AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

            
// Create domain
            AppDomain workerAppDomain = AppDomain.CreateDomain(workerName, null, ads);

            AppDomain.CurrentDomain.AssemblyResolve 
+= new ResolveEventHandler(CurrentDomain_AssemblyResolve);
            
// do work on proxy
            IWorker workerInstance =
                (IWorker)
                workerAppDomain.CreateInstanceAndUnwrap(CONFIG_DYNAMIC_ASSEMBLY_PROJECT,
                                                        CONFIG_DYNAMIC_ASSEMBLY_FULLY_QUALIFIED_NAME);

            
// Execute the task by invoking method on the interface instance
            
//workerInstance.DoWork();
            
//workerInstance.CopyThirdDllToCurrentDomainFolder();
            workerInstance.GenerateHtmlApi();
            workerInstance.GenerateMetaServerInterfaceXML();
            workerInstance.GenerateGameXML();


            
// Unload worker appDomain
            AppDomain.Unload(workerAppDomain);

        }

        System.Reflection.Assembly CurrentDomain_AssemblyResolve(
object sender, ResolveEventArgs args) {
            
try {
                Assembly assembly 
= System.Reflection.Assembly.Load(args.Name);
                
if (assembly != null)
                    
return assembly;
            }
            
catch { // ignore load error 
            }

            
// *** Try to load by filename - split out the filename of the full assembly name
            
// *** and append the base path of the original assembly (ie. look in the same dir)
            
// *** NOTE: this doesn't account for special search paths but then that never
            
//           worked before either.
            string[] Parts = args.Name.Split(',');
            
string File = FilePathConstant.CONFIG_ASSEMBLY_POOL + "\\" + Parts[0].Trim() + ".dll";

            
return System.Reflection.Assembly.LoadFrom(File);

        }
    }


如果IWorker workerInstance =
                (IWorker)
                workerAppDomain.CreateInstanceAndUnwrap(CONFIG_DYNAMIC_ASSEMBLY_PROJECT,
                                                        CONFIG_DYNAMIC_ASSEMBLY_FULLY_QUALIFIED_NAME);
强制转换为IWorker失败,则引发事件ResolveEventHandler

转载于:https://www.cnblogs.com/joe-yang/archive/2009/10/02/1577395.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值