3

これが取引です。私はいくつかのプロジェクトを含むソリューションを持っています:

  • ラッパー プロジェクト - これは、現在デバッグ中に Windows サービスの代わりになっている単なるコンソール アプリです。
  • ワーカー プロジェクト - コードの内容が含まれています。このようにして、頭を悩ませることなく、Windows サービスのコードを簡単にデバッグできます。
  • プラグイン ライブラリ プロジェクト - これには、プラグインの具体的なインスタンスを新しく作成するためのプラグイン ファクトリが含まれています。
  • プラグイン プロジェクト - これには、プラグインの具体的な実装が含まれています。

私のラッパー アプリケーションには、私のプラグインが自己構成のために直接参照する必要がある私の app.config が含まれています。このように、私のラッパー アプリケーションは、アダプタ ファクトリを呼び出してプラグインのインスタンスを新たに作成する必要があること以外、何も知る必要はありません。

<configuration>
  <appSettings>
    <add key="Plugin" value="Prototypes.BensPlugin" />
    <add key="Prototypes.BensPlugin.ServiceAddress" value="http://localhost/WebServices/Plugin.asmx" />
    <add key="Prototypes.BensPlugin.Username" value="TestUserName" />
    <add key="Prototypes.BensPlugin.Password" value="TestPassword" />
  </appSettings>
</configuration>

ラッパー プロジェクト:

using Worker;

public class Program
{
    public static void Main()
    {
        var serviceProc = new ServiceProcess();
        serviceProc.DoYourStuff();
    }
}

ワーカー プロジェクト:

using PluginLibrary;

namespace Worker
{
    public class ServiceProcess
    {
        public string GetRequiredAppSetting(string settingName)
        {
            /* Code to get a required configuration setting */
        }

        public void DoYourStuff()
        {
            string pluginTypeName = GetRequiredAppSetting("Plugin"); 
            //At this point, pluginTypeName = "Prototypes.BensPlugin"
            Type type = Type.GetType(pluginTypeName); //type == null, wth!?

            //string testTypeName = new BensPlugin().GetType().ToString();
            ///At this point, testTypeName = "Prototypes.BensPlugin"
            //Type testType = Type.GetType(testTypeName)
            ///And testType still equals null!

            if (type != null)
            {
                IPlugin plugin = PluginFactory.CreatePlugin(type);
                if (plugin != null)
                plugin.DoWork();
            }
        }
    }
}

プラグイン ライブラリ:

namespace PluginLibrary
{
    public interface IPlugin
    {
        void DoWork();
    }

    public class PluginFactory
    {
        public IPlugin CreatePlugin(Type pluginType)
        {
            return (IPlugin)Activator.CreateInstance(pluginType);
        }
    }
}

プラグイン:

using PluginLibrary;

namespace Prototypes
{
    public class BensPlugin : IPlugin
    {
        public string ServiceAddress { get; protected set; }
        public string username { get; protected set; }
        public string password { get; protected set; }

        public void DoWork()
        {
            Trace.WriteLine("Ben's plugin is working.");
        }

        public BensPlugin()
        {
            /* Code to self configure from app.config */
        }
    }
}

よし、これで準備は整った。私が立ち往生しているところは、私が参照するときの私のワーカープロジェクトにありますType.GetType(pluginTypeName)。MypluginTypeNameは構成から正しく引き出されていますが、 をType.GetType(pluginTypeName)返しますnull。コード内の同じ場所で、プラグインのインスタンスを直接新しくしようとしました。

var obj = new BensPlugin();

これは問題なく動作し、でobj.GetType().ToString()構成したのとまったく同じ文字列を返しますapp.config

Type.GetType(pluginTypeName)コードのその時点で具体的なオブジェクトを新しく作成できるのに、失敗する理由を誰か教えてもらえますか?

4

3 に答える 3

8

型が配置されているアセンブリを指定する必要がある場合があります。

<add key="Plugin" value="Prototypes.BensPlugin, TheAssemblyName" />
于 2009-11-06T15:50:18.457 に答える
2

を呼び出す代わりにType.GetType(pluginTypeName)、 を試してくださいType.GetType(pluginTypeName, true)。boolean パラメーターは、呼び出しが失敗した場合に、戻るのではなく、例外をスローする必要があるかどうかを示します。nullこの方法では、GetType が失敗する理由について、単なる不可解なnull!

于 2009-11-06T15:55:40.147 に答える
1

pluginTypeName はアセンブリ修飾名を使用していますか? pluginTypeName を含むアセンブリはロードされていると表示されていますか?

アセンブリ修飾名を使用している場合、.NET はアセンブリを自動的にロードできるはずです。そうでない場合はType.GetType()、要求された型を含むアセンブリを見つけることができないため、null を返していると思います。

于 2009-11-06T15:50:43.733 に答える