我做了一个网站为A,这个网站单独运行没有问题;我现在又新建了一个网站B,我现在需要将这个B网站当成一个应用插件加到A中,所以,我就将网站B的相关文件(比如就只有一个default.aspx)放到网站A的APPS目录下(比如<Apps/B/default.aspx),然后将B网站的Bin目录下的dll也拷贝到APPS的B目录下(Apps/B/Lib/b.dll),然后我再A的global.asax的application_start里面加载B的dll文件。但是却总是报错“ 未能加载类型“Plugs.Application.Default”。代码如下:void Application_Start(object sender, EventArgs e) 
    {
        //在应用程序启动时运行的代码
        Framework.PlugsHostService.Instance.LoadPlugs();
    }-------------private bool alreadyLoad = false;//查找所有的插件的路径
        private static List<string> FindPlugin()
        {
            List<string> PluginPaths = new List<string>();
            try
            {
                //获取当前程序的启动路径
                string path = appLocation;
                //合并路径,指向插件所在的目录
                path = Path.Combine(path, "Lib");
                string[] fileNames = Directory.GetFiles(path, "*.dll");
                foreach (string fileName in fileNames)
                {
                    PluginPaths.Add(fileName);
                }
            }
            catch (Exception exp)
            {
                throw exp;
            }
            return PluginPaths;
        }public void LoadPlugs()
        {
            if (alreadyLoad)
            {
                return;
            }
            List<string> PluginPaths = FindPlugin();
            PluginPaths = DeleteInvalidPlugin(PluginPaths);
            foreach (string path in PluginPaths)
            {
                try
                {
                    //获得 文件名称 
                    string asmFile = path;
                    string asmName = System.IO.Path.GetFileNameWithoutExtension(asmFile);
                    if (asmFile != string.Empty)
                    {                        // 利用反射,构造DLL文件的实例
                        System.Reflection.Assembly asm = System.Reflection.Assembly.LoadFile(asmFile);                        Type[] t = asm.GetExportedTypes();
                        foreach (Type type in t)
                        {
                            if (type.GetInterface(typeof(IPlugs).FullName) != null)
                            {
                                IPlugs iPlugs = (IPlugs)System.Activator.CreateInstance(type);
                                // 在主程序中使用这个类的实例
                                //AppDomain.CurrentDomain.Load(asm.GetName());
                                //AppDomain.CurrentDomain.ExecuteAssembly(asmFile);//.ExecuteAssembly(asmFile);
                                AppDomain.CurrentDomain.Load(asm.FullName, AppDomain.CurrentDomain.Evidence); //调试时,到这里就报错
                            }
                        }
                    }
                    alreadyLoad = true;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }

解决方案 »

  1.   

    我如果把B的dll直接放到A的bin目录下就可以运行;但是这样就违背了我将B作为插件的意图了。
      

  2.   

    msdn:
    http://msdn.microsoft.com/zh-cn/library/system.reflection.assembly.loadfile.aspx
      

  3.   


    使用模板页是什么意思?我是要把其他应用做为一个插件挂接到现有的应用A上。你是让我再模板页里加载B里的DLL还是什么?
      

  4.   


    我用
    Assembly.LoadFile("D:\\Lib\\application.dll")加载后
    我还需要用AppDomain.CurrentDomain.Load("D:\\Lib\\Application.dll", AppDomain.CurrentDomain.Evidence);的时候会报错:未能加载文件或程序集“D:\\Lib\\Application.dll”或它的某一个依赖项。给定程序集名称或基本代码无效。 (异常来自 HRESULT:0x80131047) 
      

  5.   

    反射?
    public void test1() {    System.Reflection.Assembly ass;    Type type ;    object obj;try{    ass = System.Reflection.Assembly.LoadFile(@"d:TestReflect.dll");  //要读取的dll路径    type = ass.GetType("Webtest.ReflectTest");  //必须使用名称空间+类名称(如果又空间名) ReflectTest 为类名    System.Reflection.MethodInfo method = type.GetMethod("WriteString");   //方法的名称    obj = ass.CreateInstance("Webtest.ReflectTest");   //必须使用名称空间+类名称     string s = (string)method.Invoke(obj,new string[]{"jianglijun"});    //实例方法的调用      Response.Write(s+" ");     method = type.GetMethod("WriteName");   //方法的名称     s = (string)method.Invoke(null,new string[]{"jianglijun"});    //静态方法的调用     Response.Write(s+" ");     method = type.GetMethod("WriteNoPara");   //无参数的实例方法     s = (string)method.Invoke(obj,null);     Response.Write(s+" ");     method = null;}catch(Exception ex){         Response.Write(ex+" ");}   finally           {                ass = null;                type = null;                obj = null;            }}
      

  6.   


    我是要在Application_Start的时候先加载d:\\Lib\\application.dll这个dll,然后再将这个dll注册到当前应用程序域里,所以我用AppDomain.CurrentDomain.Load将其加载;然后我在访问指定页面的时候,就会用到application.dll这个;不是要通过反射立马用dll里的方法
      

  7.   

    我觉得可以用codeBase加载:
    否则lz访问B的类都必须使用反射。<runtime>  
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">  
          <!--<probing privatePath="bin;bin2\subbin;bin3"/>-->  
          <dependentAssembly>  
            <assemblyIdentity name="MyCheckBoxCtrl" />  
            <codeBase href="ExtDlls/MyCheckBoxCtrl.dll" />  
          </dependentAssembly>  
        </assemblyBinding>  
      </runtime>  
      

  8.   

    当然还有个问题,如果加载的目录是bin子目录以外的目录,比如平级目录等,则要求这个dll是强命名的程序集。
      

  9.   


    我现在就是将dll放到Bin目录以外的。如果用codeBase的话,那是不是就可以直接用AppDomain.CurrentDomain.Load来直接加载了呢?谢谢