How can I pass an argument to a C# plug-in being loaded through Assembly.CreateInstance?

大憨熊 提交于 2020-01-02 04:12:09

问题


What I have now (which successfully loads the plug-in) is this:

Assembly myDLL = Assembly.LoadFrom("my.dll");
IMyClass myPluginObject = myDLL.CreateInstance("MyCorp.IMyClass") as IMyClass;

This only works for a class that has a constructor with no arguments. How do I pass in an argument to a constructor?


回答1:


You cannot. Instead use Activator.CreateInstance as shown in the example below (note that the Client namespace is in one DLL and the Host in another. Both must be found in the same directory for code to work.)

However, if you want to create a truly pluggable interface, I suggest you use an Initialize method that take the given parameters in your interface, instead of relying on constructors. That way you can just demand that the plugin class implement your interface, instead of "hoping" that it accepts the accepted parameters in the constructor.

using System;
using Host;

namespace Client
{
    public class MyClass : IMyInterface
    {
        public int _id;
        public string _name;

        public MyClass(int id,
            string name)
        {
            _id = id;
            _name = name;
        }

        public string GetOutput()
        {
            return String.Format("{0} - {1}", _id, _name);
        }
    }
}


namespace Host
{
    public interface IMyInterface
    {
        string GetOutput();
    }
}


using System;
using System.Reflection;

namespace Host
{
    internal class Program
    {
        private static void Main()
        {
            //These two would be read in some configuration
            const string dllName = "Client.dll";
            const string className = "Client.MyClass";

            try
            {
                Assembly pluginAssembly = Assembly.LoadFrom(dllName);
                Type classType = pluginAssembly.GetType(className);

                var plugin = (IMyInterface) Activator.CreateInstance(classType,
                                                                     42, "Adams");

                if (plugin == null)
                    throw new ApplicationException("Plugin not correctly configured");

                Console.WriteLine(plugin.GetOutput());
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.ToString());
            }
        }
    }
}



回答2:


call

public object CreateInstance(string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes)

instead. MSDN Docs

EDIT: If you are going to vote this down, please give insight into why this approach is wrong/or not the best way.




回答3:


You can with Activator.CreateInstance




回答4:


Activator.CreateInstance takes a Type and whatever you want to pass to the Types constructor.

http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx




回答5:


You can also not use Activator.CreateInstance, which could perform better. See below StackOverflow question.

How to pass ctor args in Activator.CreateInstance or use IL?



来源:https://stackoverflow.com/questions/134481/how-can-i-pass-an-argument-to-a-c-sharp-plug-in-being-loaded-through-assembly-cr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!