- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
由于我的应用程序架构发生了变化,我最近出现了循环依赖。
该应用程序依赖于通过 MEF 加载插件的插件管理器。直到一切正常,因为它看起来像这样:
// model.cs
[Export("Model")]
public class Model
{
public PluginManager PM { get; set; }
[ImportingConstructor]
public Model( [Import] PluginManager plugin_manager)
{
PM = plugin_manager;
}
}
// pluginmanager.cs
[Export(typeof(PluginManager))]
public class PluginManager
{
[ImportMany(typeof(PluginInterface))]
private IEnumerable<PluginInterface> Plugins { get; set; }
}
插件看起来像这样:
// myplugin.cs
[Export(typeof(PluginInterface))]
public class MyPlugin : PluginInterface
{
}
但现在我遇到了一种情况,我希望所有插件都能够通过接口(interface)查询 PluginManager(或可能的任何其他对象),以了解系统中的其他插件,从而了解它们的功能。我通过添加另一个接口(interface)“解决”了这个问题,我们称之为 PluginQueryInterface。然后我让模型实现了这个接口(interface)。
[Export("Model"))]
[Export(typeof(PluginQueryInterface))]
public class Model : PluginQueryInterface
{
// same as before
}
然后插件签名看起来像这样:
// 1st possible implementation
[Export(typeof(PluginInterface))]
public class MyPlugin : PluginInterface
{
[Import(typeof(PluginQueryInterface))]
public PluginQueryInterface QueryInterface { get; set; }
public MyPlugin() {}
}
或者这个
// 2nd possible implementation
[Export(typeof(PluginInterface))]
public class MyPlugin : PluginInterface
{
private PluginQueryInterface QueryInterface { get; set; }
[ImportingConstructor]
public MyPlugin( [Import] PluginQueryInterface query_interface)
{
QueryInterface = query_interface
}
}
2 实现很明显是一个循环引用,因为插件要求在创建插件之前创建 PluginQueryInterface,但是 PluginQueryInterface 是模型,它必须导入 PluginManager,它在turn 需要创建的所有 PluginInterfaces... 我在启动时确实遇到了 MEF 循环依赖错误。
1st 实现对我来说不像是循环引用。如果 PluginQueryInterface 是一个属性,那么我认为它不会被解析直到它被使用。而且构造函数根本不使用它。那么为什么 PluginManager 不愉快地创建我所有的 MyPlugins 呢?在这两种情况下,我都遇到了相同的 MEF 错误。
我试图通过让 PluginManager 实现 PluginQueryInterface 来解决这个问题,因为 a) 它无论如何都有意义 b) 它是一个 known way of dealing with circular dependencies -- 使两个相互依赖的类依赖于第三个类。现在的问题是我得到了一个不同的 MEF 错误!它是这样说的:
GetExportedValue cannot be called before prerequisite import 'Company.App.PluginManager..ctor(Parameter="database_filepath", ContractName="PluginManager.filename")' has been set.
WTF?我在代码中设置了断点,并且在调用 GetExportedValue 之前设置了导出值 PluginManager.filename
。
我完全被难住了。现在将不胜感激任何意见或建议。几个小时以来,我一直在用头撞着覆盖着 MEF 的墙,试图调试这个问题。
(更新)
我之前没有考虑到这一点,但这可能是插件之间的差异,所以我删除了两个插件之一,现在我的应用程序加载时没有 MEF 错误。我把它加回去,它又失败了。然后我删除了另一个插件,它起作用了。所以看起来这是其他一些 MEF 错误。就好像它不希望我加载多个具有特定接口(interface)的插件...但我正在使用 ImportMany,并且它不会表现为某种 CardinalityException
?
更新
我不明白 MEF 的这一部分,希望这里有人能解释一下它的全部内容。进入代码一段时间后,我发现我的错误源于MEF在找到值后删除了导入定义!
private bool TryGetImportValue(ImportDefinition definition, out object value)
{
lock (this._lock)
{
if (this._importValues.TryGetValue(definition, out value))
{
this._importValues.Remove(definition); // this is the line that got me
return true;
}
}
value = null;
return false;
}
我以前从未遇到过这个问题,坦率地说,我很难理解我现在对我的导入和导出所做的事情,这使得这个问题浮出水面。我假设我正在做 MEF 设计者不打算让任何人做的事情。我可以盲目地注释掉 this._importValues.Remove(definition);
,但这不可能是正确的。我的猜测是,这将归结为我使用的 MEF 属性,但由于导入此值的插件具有 CreationPolicy.Shared
的创建策略,为什么我会遇到问题?
最佳答案
好吧,我有一个可能的解决方案。我没有任何使用它的经验,但使用 Lazy
实例化似乎有帮助。至少我可以继续前进,而不必更改我不完全理解的 MEF 代码。
关于c# - MEF 错误,是循环依赖,现在是其他东西,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3696893/
我似乎无法让它发挥作用。我已经尝试过在线样本,但没有一个正是我需要的。基本上我希望能够显示从给定日期过去的天数。我下面的示例是 HTML 和 PHP 的组合,出于某些原因我不得不这样做。 Date
Closed. This question needs to be more focused。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅关注editing this post的一个问题。
在此处搜索“线程关联”的答案,我发现人们对此很感兴趣,但没有什么理由可以节省可能获得稳定的 QueryPerformanceTimer 结果。 假设一个现代操作系统和一个现代 2-4 插槽工作站/服务
我有一个称为main-app的聚合物元素:
我有一个表,我想在每个插入时间记录每个订单的时间戳。但是,我得到的时间戳值为零。 这是我的架构: CREATE TABLE IF NOT EXISTS orders( orde
我正在使用 MongoDB Atlas 来托管数据库并使用这个无服务器函数查询数据: import { NextApiRequest, NextApiResponse } from "next"; /
苹果卸下了转义键,并用OLED触摸条替换了它。这对emacs用户具有影响,特别是对于具有数十年肌肉内存力才能克服此变化的UNIX/emacs用户而言。幸运的是,触摸栏逃生键似乎总是在您需要的时候出现,
抱歉,我对 DbGrids 还很陌生。 我是否应该使用查询的字段编辑器并以某种方式添加一个捕获 TIMEDIFF 的新字段,然后将其添加为我的 DbGrid 中的列? 或者我可以/应该跳过字段编辑器并
正如一本相当古老的书XUnit Patterns所写,NUnit 2.0不会为每个测试创建新的测试夹具,因此,如果测试正在操纵夹具的某种状态,则该夹具会被共享并且可能导致各种不良副作用。 还是一样吗?
我知道自2016年4月以来,Youtube API的默认配额限制为1M。 如果要增加它,我们需要向Google 发送请求。 我想知道我们可以要求的配额限制的最大值是多少? 最佳答案 根据Google开
这个问题不太可能对任何 future 的访客有帮助;它只与一个较小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,通常不适用于全世界的互联网受众。如需帮助使此问题更广泛适用,visit the
{ "size": 0, "query": { "range": { "LogTime": { "gte": "now-1d",
当我尝试从终端编译这个简单的代码时: #include int main(void) { printf("%f\n",sqrt(10)); return 0; } 使用 gcc mai
我正在尝试筛选抓取一个 html 页面,以便我可以从中提取所需的有值(value)的数据并将其放入文本文件中。到目前为止,一切进展顺利,直到我在 html 页面中遇到了这个: In inventor
这是我的 结果 MySQL 表的示例: 我想将特定用户的所有日期向前移动相同的时间间隔,以便该用户的最高日期是当前时间戳。我知道如何获取以天为单位的间隔: /* result is 823 */ SE
我有一个函数需要从主视图中的几个不同位置调用。我们称它为 updateFunction。 我这样声明: - (void)updateFunction { //updates some vari
我正在尝试找出如何以某种方式嵌套回调。 var alpha = function(callback){ var x = 5; if(x > 2){ callback()
为什么我收到RangeError:超出最大调用堆栈错误?我正在尝试解析文本以找到数学并解决它。它一直有效,直到我开始实现括号'。我试图找出错误,但就是无法弄清楚。 我的代码: var alg = {
我记得几年前,没有使用 SSL 的原因之一是它占用了大量资源,因此影响了应用程序的性能。 如今,以当前的技术,这仍然是一个需要牢记的点吗? 这个问题的出现是因为一位同事担心使用 SSL 会影响他的应用
我正在将我的数据库从 sqlserver 迁移到 mysql当我在 sqlserver 中使用 getDate() 函数时,mysql 中的替换是 Now()但是 Now() 没有返回 getDate
我是一名优秀的程序员,十分优秀!