gpt4 book ai didi

c# - 内置的 Ninject 程序集加载器是否有错误处理

转载 作者:太空宇宙 更新时间:2023-11-03 13:21:24 24 4
gpt4 key购买 nike

我写了一个插件管理器

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("*.dll")

除非从程序集导出类型时出现任何错误,否则 Kernel.Load 会崩溃且无法进行错误处理。我不希望加载单个插件程序集失败导致我的应用程序崩溃。我的解决方案是唯一可行的方法还是 Ninject 有一些可用的错误处理?

最佳答案

我认为 try { } catch { }围绕每个 Kernel.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() 上将绑定(bind)添加到内核或 .To(..) ,因为所有其他流畅的语法方法都是可选的。因此,如果 .When() 中存在异常, .InScope() ,.. 任何其他可选方法,您将得到一个不完整的绑定(bind),因此很可能是一个有问题的软件。

(但是我怀疑大多数错误不会在创建绑定(bind)时出现,而是在激活绑定(bind)时出现。而且您没有受到保护。)

据我所知,一旦您添加了绑定(bind),就无法从 ninject 中删除绑定(bind)。除了 .Rebind() - 但这总是用不同的绑定(bind)替换绑定(bind)。所以不,我不认为有“异常回滚”之类的东西。

所以我们必须寻找替代解决方案。有一个:子内核。 https://github.com/ninject/ninject.extensions.childkernel

将每个插件加载到它自己的子内核中。如果 fooplugin.dll 加载失败,请处理子内核。万一它有效..那么你很高兴! :)这也有插件不能相互影响的优点。想象一下两个插件就可以了 IBindingRoot.Bind<string>().ToConstant("some constant") ;-)

(请注意,我还没有测试是否在父内核“按预期”工作之前处理子内核,所以你应该先测试一下。很简单,对吧?)

关于c# - 内置的 Ninject 程序集加载器是否有错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24040395/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com