如何在运行时加载程序集并创建类实例?

21

我有一个程序集(assembly)。这个程序集里包含了一个类和接口。我需要在运行时加载这个程序集,并创建这个类的一个对象,同时还想使用这个接口。

Assembly MyDALL = Assembly.Load("DALL"); // DALL is name of my dll
Type MyLoadClass = MyDALL.GetType("DALL.LoadClass"); // LoadClass is my class
object obj = Activator.CreateInstance(MyLoadClass);

这是我的代码。如何改进它?


还有一个问题,如果正在加载的dll需要另一个dll,我能同时加载多个dll吗? - NewDTinStackoverflow
3个回答

19

如果您的程序集在GAC或bin中,请在类型名称末尾使用程序集名称,而不是Assembly.Load()

object obj = Activator.CreateInstance(Type.GetType("DALL.LoadClass, DALL", true));

13

你应该使用动态方法来进行优化。它比反射更快。

下面是一个使用动态方法创建对象的示例代码:

public class ObjectCreateMethod
{
    delegate object MethodInvoker();
    MethodInvoker methodHandler = null;

    public ObjectCreateMethod(Type type)
    {
        CreateMethod(type.GetConstructor(Type.EmptyTypes));
    }

    public ObjectCreateMethod(ConstructorInfo target)
    {
        CreateMethod(target);
    }

    void CreateMethod(ConstructorInfo target)
    {
        DynamicMethod dynamic = new DynamicMethod(string.Empty,
                    typeof(object),
                    new Type[0],
                    target.DeclaringType);
        ILGenerator il = dynamic.GetILGenerator();
        il.DeclareLocal(target.DeclaringType);
        il.Emit(OpCodes.Newobj, target);
        il.Emit(OpCodes.Stloc_0);
        il.Emit(OpCodes.Ldloc_0);
        il.Emit(OpCodes.Ret);

        methodHandler = (MethodInvoker)dynamic.CreateDelegate(typeof(MethodInvoker));
    }

    public object CreateInstance()
    {
        return methodHandler();
    }
}

//Use Above class for Object Creation.
ObjectCreateMethod inv = new ObjectCreateMethod(type); //Specify Type
Object obj= inv.CreateInstance();

这个方法所需时间仅为Activator所需时间的1/10。

请查看http://www.ozcandegirmenci.com/post/2008/02/Create-object-instances-Faster-than-Reflection.aspx


需要指定程序集的名称吗? - paz
如何更改代码以调用带有参数的构造函数,例如另一个对象? - DRobertE

2

Check out http://www.youtube.com/watch?v=x-KK7bmo1AM To modify his code to load multiple assemblies use

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            string assemblyName = args.Name.Split(',').First();
            using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("YourNamespace." + assemblyName + ".dll"))
            {
                byte[] assemblyData = new byte[stream.Length];
                stream.Read(assemblyData, 0, assemblyData.Length);
                return Assembly.Load(assemblyData);
            }
        }
In your main method put
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
Be sure to add your assemblies to your project and change the build action property to "Embedded Resource".


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接