为什么我不能使用Type.GetType()来查找app.config中引用的插件实例的类型?

Ben*_*ter 3 .net c# factory-pattern

所以这是交易.我有我的解决方案,里面有几个项目:

  • 一个包装器项目 - 这只是一个控制台应用程序,在调试期间当前代表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>
Run Code Online (Sandbox Code Playgroud)

包装项目:

using Worker;

public class Program
{
    public static void Main()
    {
        var serviceProc = new ServiceProcess();
        serviceProc.DoYourStuff();
    }
}
Run Code Online (Sandbox Code Playgroud)

工人项目:

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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

插件库:

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

    public class PluginFactory
    {
        public IPlugin CreatePlugin(Type pluginType)
        {
            return (IPlugin)Activator.CreateInstance(pluginType);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

插入:

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 */
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

好的,这样就可以了.在我参考的时候,我正在工作的地方Type.GetType(pluginTypeName).我pluginTypeName正在从配置中正确拉出,但Type.GetType(pluginTypeName)返回null.我已尝试直接在代码中的同一位置新建一个插件实例:

var obj = new BensPlugin();
Run Code Online (Sandbox Code Playgroud)

这很好用,并obj.GetType().ToString()返回与我在配置中完全相同的字符串app.config.

任何人都可以告诉我为什么我可以在代码中创建一个具体的对象,但Type.GetType(pluginTypeName)会失败?

Fre*_*örk 8

可能需要指定类型所在的程序集:

<add key="Plugin" value="Prototypes.BensPlugin, TheAssemblyName" />
Run Code Online (Sandbox Code Playgroud)