5

私が今持っているもの(プラグインを正常にロードする)はこれです:

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

これは、引数のないコンストラクターを持つクラスに対してのみ機能します。コンストラクターに引数を渡すにはどうすればよいですか?

4

5 に答える 5

12

それはいけません。代わりに、以下の例に示すようにActivator.CreateInstanceを使用します(クライアントの名前空間は1つのDLLにあり、ホストは別のDLLにあることに注意してください。コードが機能するには、両方が同じディレクトリにある必要があります)。

ただし、真にプラグ可能なインターフェイスを作成する場合は、コンストラクターに依存するのではなく、インターフェイスで指定されたパラメーターを受け取るInitializeメソッドを使用することをお勧めします。そうすれば、コンストラクターで受け入れられたパラメーターを受け入れることを「期待」するのではなく、プラグインクラスがインターフェイスを実装するように要求できます。

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());
            }
        }
    }
}
于 2008-09-25T17:38:18.410 に答える
3

電話

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

代わりは。 MSDN ドキュメント

編集:これに反対票を投じる場合は、このアプローチが間違っている/最善の方法ではない理由を教えてください。

于 2008-09-25T16:54:11.793 に答える
2

Activator.CreateInstanceでできます

于 2008-09-25T16:51:15.857 に答える
1

Activator.CreateInstance は、Type と、Types コンストラクターに渡したいものを受け取ります。

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

于 2008-09-25T16:53:28.020 に答える
0

Activator.CreateInstance を使用することもできません。以下の StackOverflow の質問を参照してください。

Activator.CreateInstance で ctor 引数を渡す方法、または IL を使用する方法は?

于 2010-06-17T03:15:03.403 に答える