// This class is deployed as an assembly consisting of one DLL, 
// called HelloWorld.dll.
using System;
public class HelloWorld {
   // Constant Hello World string.
   private const String m_helloWorld = "Hello World";
   // Default public constructor.
   public HelloWorld() {
   }
   // Print "Hello World" plus the passed text.
   public void PrintHello(String txt) {
      // Output to the Console.
      Console.WriteLine(m_helloWorld + " " + txt);
   }
}// Illustrates reflection's late binding functionality.
// Calls the PrintHello method on a dynamically loaded 
// and created instance of the HelloWorld class.
using System;
using System.Reflection;
public class CSharpLateHello {
   public static void Main() {
      // Load the assembly to use.
      Assembly assem = Assembly.Load("HelloWorld");
      // Get the type to use from the assembly.
      Type helloType = assem.GetType("HelloWorld");
      // Get the method to call from the type.
      MethodInfo printMethod = helloType.GetMethod("PrintHello");
      // Create an instance of the HelloWorld class.
      Object obj = Activator.CreateInstance(helloType);
      // Create the args array.
      Object[] args = new Object[1];
      // Set the arguments.
      args[0] = "From CSharp Late Bound";
      // Invoke the PrintHello method.
      printMethod.Invoke(obj, args);
   }
}
InvokeMember 和 CreateInstance
使用 Type.InvokeMember 可调用类型的成员。各个类(如 System.Activator 和 System.Reflection.Assembly)的 CreateInstance 方法是特殊形式的 InvokeMember,它们可新建特定类型的实例。Binder 类用于在这些方法中进行重载决策和参数强制。以下代码示例显示参数强制(类型强制)和成员选择三种可能的组合。在第 1 种情况中,不需要任何参数强制或成员选择。在第 2 种情况中,只需要成员选择。在第 3 种情况中,只需要参数强制。[C#]
public class CustomBinderDriver
{
   public static void Main (string[] arguments)
   {
   Type t = typeof (CustomBinderDriver);
   CustomBinder binder = new CustomBinder();
   BindingFlags flags = BindingFlags.InvokeMethod|BindingFlags.Instance|
      BindingFlags.Public|BindingFlags.Static;   //Case 1. Neither argument coercion nor member selection is needed.
   args = new Object[] {};
   t.InvokeMember ("PrintBob", flags, binder, null, args);   //Case 2. Only member selection is needed.
   args = new Object[] {42};
   t.InvokeMember ("PrintValue", flags, binder, null, args);   //Case 3. Only argument coercion is needed.
   args = new Object[] {"5.5"};
   t.InvokeMember ("PrintNumber", flags, binder, null, args);
   }   public static void PrintBob ()
   {
      Console.WriteLine ("PrintBob");
   }   public static void PrintValue (long value)
   {
      Console.WriteLine ("PrintValue ({0})", value);
   }
   public static void PrintValue (String value)
   {
      Console.WriteLine ("PrintValue\"{0}\")", value);
   }
   
   public static void PrintNumber (double value)
   {
      Console.WriteLine ("PrintNumber ({0})", value);
   }
}

解决方案 »

  1.   

    where did you get this code?
    授人以鱼不如授人以渔,谢谢了~~
      

  2.   

    还有用这种方法是否要用到Strong key?
      

  3.   

    Assembly subAppAssembly = Assembly.LoadFrom(name);
    object newObject = subAppAssembly.CreateInstance(type);
      

  4.   

    我的方法:把要使用的dll放到特定目录下,dll实现特定接口,运行时读入此目录所有DLL文件,对Type循环,如果实现接口,则创建一个实例.
    如:IMyProg.ITest接口在testbase.cs中,Test类实现ITest,位于test [DLL]项目test.cs中我们在第一个项目中包含接口定义即可,运行时得到所有dll的清单string[] dllNames,然后foreach(string s in dllNames),Assembly a=Assembly.LoadFrom(s);再foreach(Type t in a.GetTypes()),if(t.GetInterface("IMyProg.ITest")!=null) ITest iTest=(ITest)  System.Activator.CreateInstance(t)
    用此种方法,我们的项目得到了极大的灵活性,不过设计时花了一些时间
      

  5.   

    to:
     north_star(北极星) 你认为设计需要多少时间?其实很简单。
    下面是一个简单的方案:
    protected void Application_Start(Object sender, EventArgs e)
    {
    Assembly a1=typeof(EM.Msg).Assembly;
    System.Text.StringBuilder sb=new System.Text.StringBuilder();
    foreach(Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
    {
    foreach(AssemblyName an in asm.GetReferencedAssemblies())
    {
    if(an.FullName==a1.FullName)
    {
    foreach(Type t in asm.GetTypes())
    {
    if(t.IsSubclassOf(typeof(EM.Msg)))
    {
    ConstructorInfo ci=t.GetConstructor(new Type[0]);
    if(ci!=null)
    {
    EM.Msg msg=ci.Invoke(new object[0]) as EM.Msg;
    sb.Append(msg.GetMessage());
    sb.Append("<br>");
    }
    }
    }
    break;
    }
    }
    }
    Application["msg"]=sb.ToString();
    }
    其中,,EM.Msg是EMMsg.dll里的一个abstract class
    用asm.GetReferencedAssemblies()可以得到所有引用EMMsg.dll的Assembly
    这个方法好处是它不需要循环mscorlib等大规模的类库,效率非常的高。如果想效率再高点,
    可以这样:
    EMMsg.dll 定义基本的interface或abstract class
    Global.dll(包含GlobalApplication的那个)   - - - - > EMMsg.dll
    负责执行类似上面代码的过程。
    Addin.dll(包含扩展的类,但是这个类已经没有必要引用EMMsg.dll了)
    AddinAdapter.dll - - - - > EMMsg.dll那么在Global里,可以查到这两个Assembly引用了EMMsg.dll:Global,AddinAdapter然后调用AddinAdapter.Adapter.GetMessage() 
    。注释---- ( GetMessate -> Addin.TrueService.GetMessage() )这个方案虽然多了个AddinAdapter,
    但是灵活在:Addin.TrueServivce已经不需要有什么继承和实现上的约束了。
    因为它是被AddinAdapter所知道的。而且,这些Assembly都是很小的,所以循环Type的时候花的时间很少
      

  6.   

    还有,config里指定的目录(默认是bin)下的所有dll都会被装载的。
    所以你不需要自己去加载那些dll
      

  7.   

    这应该是实现VB中CreateObject方法,好象还没什么好的方法出来.
    我也在找.
      

  8.   

    http://www.dotnet247.com/247reference/msgs/11/58261.aspx
      

  9.   

    to Lostinet(迷失网络):
    我所说的花时间设计,指的是接口功能的取舍,因为要应付客户不断变化的需求,力争设计成功后,如果需要更改不会对程序框架造成大的冲击,并且容易维护
      

  10.   

    哦。.
    那是具体程序的接口的实现上了。而不是加载类型的实现上.
    我使用的是统一的
    public ITypeProvider
    {
        Type QueryType(Type t);
    }
    应用程序框架(OA-CRM-DESKTOP)
    负责维护ITypeProvider的实现列表。
    其他功能全部基于该框架开发。
    框架所希望得到外部补充的协议并没有指定要求定义在某个Assembly里。
    但有一个 TypeProvider.dll 里就定义了 ITypeProvider (也是该dll的唯一类型)
    所有基于该框架的都可以实现ITypeProvider里提供自己的扩充。
    也可以访问那列表来取得它想得到的类型。