C#学习教程:将DLL加载到具有已知唯一公共接口的独立AppDomain在主应用程序中,我对插件类型一无所知,只知道它们使用一些方法实现了公共接口ICommonInterface。所以这段代码没有帮助,因为我无法创建具有接口类型的实例。AppDomaindomain=AppDomain.CreateDomain("新域名");//对域做其他事情,比如设置安全策略stringpathToDll=@"C:myDll.dll";//要加载的dll的完整路径Typet=typeof(TypeIWantToLoad);TypeIWantToLoadmyObject=(TypeIWantToLoad)domain.CreateInstanceFromAndUnwrap(pathToDll,t.FullName);我的问题是,如果我只知道我要创建的实现类型的接口名称,我该如何加载新域中的程序集并获取实例。更新:这是我的代码:MainLib.dllnamespaceMainLib{publicinterfaceICommonInterface{voidShowDllName();}}PluginWithOutException.dll命名空间PluginWithOutException{publicclassWithOutException:MarshalByRefObject,ICommonInterface{publicvoidShowDllName(){Console.WriteLine("PluginWithOutException");}}}PluginWithException.dll命名空间PluginWithException{publicclassWithException:MarshalByRefObject,ICommonInterface{publicvoidShowDllName(){Console.WriteLine("WithException");抛出新的NotImplementedException();}}}主要应用:staticvoidMain(string[]args){stringpath=@"E:Plugins";字符串[]程序集=Directory.GetFiles(路径);列出插件=SearchPlugins(assemblies);foreach(插件中的字符串项){CreateDomainAndLoadAssebly(item);}控制台.ReadKey();}publicstaticListSearchPlugins(string[]names){AppDomaindomain=AppDomain.CreateDomain("tmpDomain");域.Load(Assembly.LoadFrom(@"E:PluginsMainLib.dll").FullName);Listplugins=newList();foreach(stringasminnames){GetTypes()wheret.IsClass&&(t.GetInterface("ICommonInterface")!=null)选择t;if(theClassTypes.Count()>0){plugins.Add(asm);}}AppDomain.Unload(domain);returnplugins;}MainLib.dll被插件和主应用程序引用主要目的是不在默认域中加载程序集,而是在另一个域中加载它们,所以当我不需要它们时,我只是卸载()域并从应用程序中卸载所有插件。目前,异常是FileNotFoundException,无法加载文件或程序集“PluginWithException,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”或其依赖项之一。系统找不到指定的文件。)FileNotFoundException,无法文件加载或程序集“PluginWithException,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”或其依赖项之一。系统找不到指定的文件。)AssemblyloadedAssembly=domain.Load(Assembly.LoadFrom(asm).FullName);(我正在尝试加载一个名为PluginWithException的插件),我删除了插件中的所有依赖项,系统除外,我在此域中加载System.dll(它正确加载并且在域中),但仍然无法加载插件到域中。我还检查过,PluginWithException有2个依赖项-mscorlib和MainLib,所有这些依赖项都加载到这个域中。更新:我在这里问了这个问题的更多细节。这个问题似乎与你想做什么有关。如何递归加载对AppDomain程序集的所有引用?加载程序集后,您可以使用Assembly.GetTypes()并迭代以查找实现该接口的类型。我不确定这是否是您需要的,我会尽力帮助您。这就是我加载插件程序集的方式。我使用帮助程序类来管理该程序集上的新AppDomain和类实例。这是辅助类:[Serializable,ClassInterface(ClassInterfaceType.AutoDual)]classhelperDomain:MarshalByRefObjectwhereT:class{#regionprivateprivateAppDomain_app_domain;私有AppDomainSetup_app_domain_info;私有字符串_assembly_class_name;私有字符串_assembly_file;私有字符串_assembly_file_name;私有T_inner_class;私人布尔_load_ok;私有字符串_loading_errors;私有字符串_path;#endregion#region.ctorpublichelperDomain(stringAssemblyFile,stringconfigFile=null,stringdomainName){this._load_ok=false;尝试{this._assembly_file=AssemblyFile;//程序集的完整路径this._assembly_file_name=System.IO.Path.GetFileName(this._assembly_file);//assmbly文件名this._path=System.IO.Path.GetDirectoryName(this._assembly_file);//从程序集路径获取根目录this._assembly_class_name=typeof(T).ToString();//要在域中从程序集实例化的类名//开始配置做mainthis._app_domain_info=newAppDomainSetup();this._app_domain_info.ApplicationBase=this._path;this._app_domain_info.PrivateBinPath=this._path;this._app_domain_info.PrivateBinPathProbe=this._path;如果(!string.IsNullOrEmpty(configFile)){this._app_domain_info.ConfigurationFile=configFile;}//让我们创建域this._app_domain=AppDomain.CreateDomain(domainName,null,this._app_domain_info);//实例化类this._inner_class=(T)this._app_domain.CreateInstanceFromAndUnwrap(this._assembly_file,this._assembly_class_name);这个._load_ok=真;}catch(Exceptionexception){//设置新的appDomain时出现问题this._load_ok=false;this._loading_errors=exception.ToString();}}#endregion#region公共属性publicstringAssemblyFile{get{return_assembly_file;}}publicstringAssemblyFileName{get{return_assembly_file_name;}}publicAppDomainAtomicAppDomain{get{return_app_d}}publicTInstancedObject{get{return_inner_class;}}publicstringLoadingErrors{get{return_loading_errors;}}publicboolLoadOK{get{return_load_ok;}}publicstringPath{get{return_path;}}#endregion}然后加载插件(每个插件在不同的文件夹中)foreach(stringpluginassemblypathinpluginspaths){//每个pluginassemblypath(如其所说..)是程序集helperDomain的完整路径isoDomain=helperDomain(pluginassemblypath,pluginassemblypath+".config",System.IO.Path.GetFileName(pluginassemblypath)+".domain");if(isoDomain.LoadOK){//我们可以访问类(.InstancedObject)的实例Console.WriteLine("Pluginloaded..."+isoDomain.InstancedObject.GetType().Name);}else{//发生了一些事情...Console.WriteLine("加载插件时出错"+pluginassemblypath+"-"+helperDomain.LoadingErrors);希望对你有帮助...以上是C#学习教程:将DLL加载到一个单独的AppDomain中,该AppDomain具有已知唯一的公共接口。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
