none
AppDomain.CurrentDomain.Load 后创建对象 RRS feed

  • 问题

  • AppDomain.CurrentDomain.Load 后如何创建一个对象呢?

      static void main()
        {
          
          System.Reflection.Assembly o1Ass = AppDomain.CurrentDomain.Load(loadFile("/testDll.dll"),loadFile("/testDll.pdb"));
    
          System.Reflection.Assembly[] Ass_s = AppDomain.CurrentDomain.GetAssemblies();
          object obj1 = o1Ass.CreateInstance("testDll.testClass");
          object obj2 = AppDomain.CurrentDomain.CreateInstance(o1Ass.FullName , "testDll.testClass");
        
        }
    
    static byte[] loadFile(string filename)
        {
          FileStream fs = new FileStream(Server.MapPath(filename), FileMode.Open);
          byte[] buffer = new byte[(int)fs.Length];
          fs.Read(buffer, 0, buffer.Length);
          fs.Close();
    
          return buffer;
        }
    

    其中obj1就可以创建对象

    而 obj2那里就会提示我说找不到依赖项或文件

    如何使用 AppDomain.CurrentDomain.CreateInstance 创建呢?

    2010年8月12日 9:45

答案

全部回复

  • win form下没问题,是不是应该放到bin目录下


    http://feiyun0112.cnblogs.com/
    2010年8月13日 0:47
    版主
  • 主要就是因为调用的这个dll文件不再bin目录下

     System.Reflection.Assembly[] Ass_s = AppDomain.CurrentDomain.GetAssemblies();
    这里已经看到 里面的确已经有了那个程序集

    但是就是调用不到

    2010年8月13日 2:56
  • 我也有参考msdn的例子来试
    using System;
    using System.IO;
    using System.Reflection;
    using System.Reflection.Emit;
    
    class Test {
      public static void Main() {
       AppDomain currentDomain = AppDomain.CurrentDomain;
    
       InstantiateMyType(currentDomain);  // Failed!
    
       currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolver);
    
       InstantiateMyType(currentDomain);  // OK!
      }
    
      static void InstantiateMyType(AppDomain domain) {
       try {
    	 // You must supply a valid fully qualified assembly name here.
         domain.CreateInstance("Assembly text name, Version, Culture, PublicKeyToken", "MyType");
       } catch (Exception e) {
         Console.WriteLine(e.Message);
       }
      }
    
      // Loads the content of a file to a byte array. 
      static byte[] loadFile(string filename) {
       FileStream fs = new FileStream(filename, FileMode.Open);
       byte[] buffer = new byte[(int) fs.Length];
       fs.Read(buffer, 0, buffer.Length);
       fs.Close();
    
       return buffer;
      }  
    
      static Assembly MyResolver(object sender, ResolveEventArgs args) {
       AppDomain domain = (AppDomain) sender;
    
       // Once the files are generated, this call is
       // actually no longer necessary.
       EmitAssembly(domain);
    
       byte[] rawAssembly = loadFile("temp.dll");
       byte[] rawSymbolStore = loadFile("temp.pdb");
       Assembly assembly = domain.Load(rawAssembly, rawSymbolStore);
    
       return assembly;
      }
    
      // Creates a dynamic assembly with symbol information
      // and saves them to temp.dll and temp.pdb
      static void EmitAssembly(AppDomain domain) {
       AssemblyName assemblyName = new AssemblyName();
       assemblyName.Name = "MyAssembly";
    
       AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);
       ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MyModule", "temp.dll", true);
       TypeBuilder typeBuilder = moduleBuilder.DefineType("MyType", TypeAttributes.Public);
    
       ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null);
       ILGenerator ilGenerator = constructorBuilder.GetILGenerator();
       ilGenerator.EmitWriteLine("MyType instantiated!");
       ilGenerator.Emit(OpCodes.Ret);
    
       typeBuilder.CreateType();
    
       assemblyBuilder.Save("temp.dll");
      }
    }
    
    

     

    这样的确成功 ,但是如果本身已经有了temp.dll的话 我略去 currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolver);
    这一步直接用

    byte[] rawAssembly = loadFile("temp.dll");
          byte[] rawSymbolStore = loadFile("temp.pdb");
          Assembly assembly = domain.Load(rawAssembly, rawSymbolStore);
    调用 也是能在能看到是有了那个程序集但是不能调用

    2010年8月13日 3:03
  • 终于解决了 需要强签名的dll 才可以加载进去直接使用 否则CLR不会从GAC中去找。

    还有问题就是 没有强签名的dll 难道就只能用

    currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolver);

    这个方式吗?

    2010年8月13日 6:47
  • 还是因为安全的问题吧,不能随意访问目录
    http://feiyun0112.cnblogs.com/
    2010年8月13日 6:55
    版主