C# 为什么可以';我是否获取Type.GetType()以查找app.config中引用的插件实例的类型?

C# 为什么可以';我是否获取Type.GetType()以查找app.config中引用的插件实例的类型?,c#,.net,factory-pattern,C#,.net,Factory Pattern,这就是交易。我有我的解决方案,其中有几个项目: 包装器项目-这只是一个控制台应用程序,在调试过程中当前正在替代windows服务 一个工作者项目——它包含代码的核心。通过这种方式,我可以轻松地调试windows服务的代码,而不会感到头痛 一个插件库项目——它包含一个插件工厂,用于创建一个插件的具体实例 一个插件项目——它包含我的插件的具体实现 我的包装器应用程序包含我的app.config,我的插件应该直接引用它进行自我配置。这样,我的包装器应用程序不需要知道任何事情,只需要调用适配器工厂来

这就是交易。我有我的解决方案,其中有几个项目:

  • 包装器项目-这只是一个控制台应用程序,在调试过程中当前正在替代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)
时,我要解决的问题是我的工作者项目。我的
pluginTypeName
正在正确地从配置中提取,但是
Type.GetType(pluginTypeName)
返回
null
。我已尝试在代码中的同一位置直接更新我的插件实例:

var obj = new BensPlugin();
这工作正常,
obj.GetType().ToString()
返回与我在
app.config
中配置的字符串完全相同的字符串


有人能告诉我为什么我可以在代码中的那个点新建一个具体对象,但是
Type.GetType(pluginTypeName)
会失败吗?

可能是您需要指定类型位于哪个程序集中:

<add key="Plugin" value="Prototypes.BensPlugin, TheAssemblyName" />

pluginTypeName是否使用程序集限定的命名?包含pluginTypeName的程序集是否显示为正在加载


如果您使用的是程序集限定名,那么.NET应该能够为您自动加载程序集;如果您没有,那么我猜
Type.GetType()
将返回null,因为它找不到包含请求类型的程序集。

请尝试调用
Type.GetType(pluginTypeName)
,而不是调用
Type.GetType(pluginTypeName,true)
。boolean参数指示调用在发生故障时是否应该抛出异常,而不是返回
null
——这样,您应该(希望)更好地描述GetType失败的原因,而不仅仅是一个神秘的
null