C# 内置的Ninject程序集加载程序是否有错误处理
我写了一个插件管理器C# 内置的Ninject程序集加载程序是否有错误处理,c#,plugins,dependency-injection,ninject,C#,Plugins,Dependency Injection,Ninject,我写了一个插件管理器 public class WeinCadPluginManager : NinjectModule, IEnableSerilog { public override void Load() { var codeBaseUrl = new Uri(Assembly.GetExecutingAssembly().CodeBase); var codeBasePath = Uri.UnescapeDataString(codeB
public class WeinCadPluginManager : NinjectModule, IEnableSerilog
{
public override void Load()
{
var codeBaseUrl = new Uri(Assembly.GetExecutingAssembly().CodeBase);
var codeBasePath = Uri.UnescapeDataString(codeBaseUrl.AbsolutePath);
var dirPath = Path.GetDirectoryName(codeBasePath);
Debug.Assert(dirPath != null, "dirPath != null");
var path = dirPath;
var types = Directory
.GetFiles(path, "*.dll")
.Select (Assembly.LoadFile)
.SelectMany (assembly =>
{
try
{
return assembly.GetExportedTypes();
}
catch (Exception e)
{
this.Serilog()
.Error
(e, "Failed to load assembly {assembly}", assembly);
return new Type[]
{
};
}
})
.Where(type=>typeof(IWeinCadPlugin).IsAssignableFrom(type))
.ToList();
foreach (var assembly in types)
{
Kernel.Bind<IWeinCadPlugin>().To(assembly).InSingletonScope();
}
}
}
除非从程序集导出类型时出现任何错误,否则
Kernel.Load
将崩溃,无法进行错误处理。我不希望加载单个插件程序集的失败导致我的应用程序崩溃。我的解决方案是唯一可行的方法,还是Ninject有一些可用的错误处理方法?我认为在每个内核周围使用尝试{}catch{}
。Load(“specificplugin.dll”)
就足够了。
您仍然需要自己查找所有程序集,但必须编写更少的代码
var codeBaseUrl = new Uri(Assembly.GetExecutingAssembly().CodeBase);
var codeBasePath = Uri.UnescapeDataString(codeBaseUrl.AbsolutePath);
var dirPath = Path.GetDirectoryName(codeBasePath);
var dllPaths = Directory.GetFiles(dirpath, "*.dll");
foreach(string dllPath in dllPaths)
{
try
{
kernel.Load(dllPath);
}
catch (Exception e)
{
this.Serilog()
.Error(e, "Failed to load assembly {assembly}", assembly);
}
}
缺点:ninject必须在.Bind()
或.to(..)
上向内核添加绑定,因为所有其他fluent语法方法都是可选的。因此,如果在.When()
,.InScope()
,。。任何其他可选方法,都会留下一个不完整的绑定,因此很可能是一个错误的软件
(但是,我怀疑大多数错误不会在创建绑定时出现,而是在激活绑定时出现。您没有受到保护。)
据我所知,一旦添加了绑定,就无法从ninject中删除它们。除了.Rebind()
——但这总是用不同的绑定替换绑定。
所以不,我不认为有什么像“在异常时回滚”
因此,我们必须寻找另一种解决办法。有一个:子内核
将每个插件加载到它自己的子内核中。如果fooplugin.dll加载失败,请处置子内核。以防万一。。好吧,你可以走了!:)
这也有一个优点,即插件之间不能相互影响。设想两个插件可以执行IBindingRoot.Bind().ToConstant(“某个常量”)
;-)
(请注意,我还没有测试在父内核“按预期”工作之前是否处理子内核,所以您应该首先测试它。足够简单,对吗?)
var codeBaseUrl = new Uri(Assembly.GetExecutingAssembly().CodeBase);
var codeBasePath = Uri.UnescapeDataString(codeBaseUrl.AbsolutePath);
var dirPath = Path.GetDirectoryName(codeBasePath);
var dllPaths = Directory.GetFiles(dirpath, "*.dll");
foreach(string dllPath in dllPaths)
{
try
{
kernel.Load(dllPath);
}
catch (Exception e)
{
this.Serilog()
.Error(e, "Failed to load assembly {assembly}", assembly);
}
}