为什么我无法使用 Type.GetType() 来查找 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();
}
}
Worker 项目:
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)
会失败?
So here's the deal. I've got my solution which has a few projects in it:
- A wrapper project - this is just a console app that's currently standing in for a windows service during debugging.
- A worker project - this contains the guts of the code. This way I can easily debug the code for the windows service without the headache.
- A plugin library project - This contains a plugin factory to new up a concrete instance of a plugin.
- A plugin project - This contains a concrete implementation of my plugin.
My wrapper application contains my app.config which my plugin should reference directly for self configuration. This way my wrapper application doesn't need to know anything other than it needs to call the adapter factory to new up the instance of the plugin.
<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>
Wrapper project:
using Worker;
public class Program
{
public static void Main()
{
var serviceProc = new ServiceProcess();
serviceProc.DoYourStuff();
}
}
Worker project:
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();
}
}
}
}
Plugin library:
namespace PluginLibrary
{
public interface IPlugin
{
void DoWork();
}
public class PluginFactory
{
public IPlugin CreatePlugin(Type pluginType)
{
return (IPlugin)Activator.CreateInstance(pluginType);
}
}
}
Plugin:
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 */
}
}
}
Okay, so that sets the stage. Where I'm coming unstuck is in my worker project when I reference Type.GetType(pluginTypeName)
. My pluginTypeName
is being pulled from the configuration correctly, but Type.GetType(pluginTypeName)
returns null
. I've tried newing up an instance of my plugin directly at that same place in the code:
var obj = new BensPlugin();
This works just fine, and obj.GetType().ToString()
returns the exact same string as I have configured in the app.config
.
Can anyone tell me why I can new up a concrete object at that point in the code, but Type.GetType(pluginTypeName)
would fail?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可能需要指定该类型位于哪个程序集中:
It could be that you need to specify which assembly the type is located in:
不要调用
Type.GetType(pluginTypeName)
,而是尝试Type.GetType(pluginTypeName, true)
。布尔参数指示调用在失败时是否应抛出异常,而不是返回 null - 这样,您应该(希望)获得更好的原因描述> GetType 失败而不仅仅是一个神秘的null
!Instead of calling
Type.GetType(pluginTypeName)
, tryType.GetType(pluginTypeName, true)
. The boolean parameter indicates if the call should throw an exception in the event of a failure, instead of returningnull
- this way, you should get a (hopefully) better description of why GetType is failing instead of just a mysteriousnull
!pluginTypeName 是否使用程序集限定命名?包含pluginTypeName 的程序集是否显示为正在加载?
如果您使用的是程序集限定名称,那么 .NET 应该能够自动为您加载程序集;如果不是,那么我会猜测
Type.GetType()
返回 null,因为它无法找到包含所请求类型的程序集。Is pluginTypeName using assembly-qualified naming? Is the Assembly that contains pluginTypeName showing as being loaded?
If you're using the Assembly-qualified name then .NET should be able to automatically load the assembly for you; if you aren't then I would guess that
Type.GetType()
is returning null since it can't locate an assembly containing the requested type.