我正在为一个ASP.NET Web API项目开发的“插件”系统看到一些奇怪的行为。插件是DLL,它们被复制到bin文件夹中。这意味着它们已经在当前的AppDomain中。
每个插件都有一个实现IPluginConfiguration的配置类。
以下类通过查找当前AppDomain中实现IPluginConfiguration接口的所有类来配置插件。这是从Global.asax.cs
调用的public class PluginConfigurator
{
/* ... */
public static void Register(HttpConfiguration config)
{
var pluginConfigs = GetPluginConfigurations();
try
{
foreach (var pluginConfigType in pluginConfigs)
{
var pluginConfig = (IPluginConfiguration) Activator.CreateInstance(pluginConfigType);
pluginConfig.Configure(config);
Logger.Log("Configured Type: {0}", pluginConfigType.FullName);
}
}
catch (ReflectionTypeLoadException e)
{
Logger.Log("Error of type: {0}", e.GetType().Name);
}
}
private static IEnumerable<Type> GetPluginConfigurations()
{
return AppDomain.CurrentDomain
.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(type => !type.IsInterface)
.Where(type => typeof(IPluginConfiguration).IsAssignableFrom(type));
}
}
我的测试插件有以下配置。
public class PluginConfiguration : IPluginConfiguration
{
/* ... */
public void Configure(HttpConfiguration config)
{
try
{
Logger.Log("Configuring test plugin");
RegisterRoutes(config);
}
catch (Exception e)
{
Logger.Log("Error of type {0} in configuration", e.GetType().Name);
}
}
/* ... */
}
所以我希望我的日志文件能够说出
Configuring test plugin
Configured Type: MyNameSpace.PluginConfiguration
或
Configuring test plugin
Error of type MyNameSpace.PluginConfiguration in configuration
Configured Type: MyNameSpace.PluginConfiguration
但实际上我只是得到了
Configured Type: MyNameSpace.PluginConfiguration
此前还有其他日志记录。我认为它可能是日志记录的问题,所以我在PluginConfiguration类中创建了一个文件,它也没有这样做。看来我的PluginConfiguration类没有被调用。
我创建了一个调用PluginConfigurator类的单元测试,并且该方法被调用。
有什么可能导致此问题或如何解决问题的建议?
答案 0 :(得分:1)
当我将代码粘贴到我正在处理的Web应用程序的Application_Start()
并从 bin >加载辅助DLL时,代码对我有效(即我看到两个日志消息) strong>文件夹。
我要做的第一件事是确保自己正在被调用的方法是在Configure()
中明确抛出异常。在这种情况下,您应该看到“类型错误:”字符串。 (也许在你的异常中抛出一个自定义字符串是绝对肯定的。)
一旦确定它被调用,您就可以开始处理日志记录问题了。我最好的猜测,曾经尝试过失败的绝望记录策略,但是会有权限。由于这可能是一个Web应用程序,因此写入权限将受到相当大的限制。您也可能遇到ASP.NET's shadow copy并且根本找不到日志文件。
在任何情况下,由于反射,你可能不遇到一个神秘的被召唤但未被召唤的情况。这很可能是一个更普通的问题。
我要做的第二件事是忘记尝试制作自定义插件系统并改用MEF,呵呵。