- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 MEF 为 WinForms 应用程序实现插件,我注意到一些我不理解的组合行为。
为了解决这个问题,我将 MEF 与 .NET 4 结合使用。
作为一种 tl;dr,关于容器和组合,这是我不清楚的地方:
ComposeParts(this)
该类的现有实例是添加到容器中还是创建了另一个实例?GetExportedValue<T>()
方法,返回的部分是否已经组成(或已填充其导入),还是我需要明确组成该部分?继续阅读以了解有关每个问题的更多详细信息...
关于第一个问题,我有一个主应用程序表单,它有一个面板,该面板将托管“普通”应用程序用户控件以及来自插件的用户控件。这个主应用程序表单实现了一个名为 IHostingForm
的接口(interface)这允许它向插件公开它自己的一些功能。此主申请表通过 IHostingForm
导出自身接口(interface),并有一个需要填写的导入。这是一个代码片段:
[Export(typeof(IHostingForm))]
public partial class frmMain : RibbonForm, IHostingForm
{
//public/private form methods here...
private CompositionContainer _container;
//An import that needs to be filled.
[ImportMany]
public IEnumerable<Lazy<IAddInController, IAddInControllerMetadata>> AddInControllers;
public frmMain()
{
//Init code here omitted to save space...
//Setup the container
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
//Temporary location while testing...
catalog.Catalogs.Add(new DirectoryCatalog(Application.StartupPath));
_container = new CompositionContainer(catalog);
try
{
//Is the current instance of the class (this) added to the
//container or does the container construct its own instance?
_container.ComposeParts(this);
}
catch (CompositionException ex)
{
//Error catching code omitted...
}
}
//IHostingForm implementation
public void AddTabToTabBar(string tabText)
{
RibbonTab rt = new RibbonTab(tabText);
//Some more init code here which I'm leaving out to save space...
this.ribbonBar1.CommandTabs.Add(rt);
}
//etc...
}
请注意上面的代码片段中它是如何导出自身的,但它也调用了 ComposeParts(this)
在构造函数中?这会创建一个单独的表单实例还是 ComposeParts(this)
足够聪明,知道使用已经存在的实例并将其添加到容器中?
这引出了我的第二个问题。由于我不确定上面使用的组合方法是否正确,我尝试在应用程序的 Program 类中创建容器,但我发现了另一种我不理解的行为。我将容器初始化代码从窗体的类中移出并移入程序中,如下所示:
static class Program
{
internal static CompositionContainer _container;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Setup the container
var catalog = New AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
catalog.Catalogs.Add(new DirectoryCatalog(Application.StartupPath));
_container = new CompositionContainer(catalog);
IHostingForm frm = _container.GetExportedValue<IHostingForm>();
//If I don't call this, the form's imports don't get satisfied
_container.CompostParts(frm);
Application.Run((Form)frm);
}
}
基于 MSDN 上的文档以及 the answer to this question , 我的印象是 GetExportedValue<T>()
方法将实例化给定类型的导出并组合它(或满足其依赖关系?),因为它是从容器中出来的。但是通过测试,似乎在从容器中获取零件后,我必须明确告诉容器组成零件才能填充其导入。这似乎与我目前所读的内容相矛盾。
我不确定这是否是多个问题。如果他们需要分开,请告诉我,我很乐意编辑这个问题并创建另一个问题。但是,对我来说,它们似乎是相关的,因为它们都在处理我对容器和组合发生的事情缺乏了解的问题。
最佳答案
Notice in the snippet above how it is exporting itself but it also calls ComposeParts(this) in the constructor? Does this create a separate instance of the form or is ComposeParts(this) smart enough to know to use the already existing instance and just add it to the container?
它“足够聪明”,因为它会按指令执行。 ComposeParts(this)
会首先查看this
需要满足哪些Import
。然后它将尝试找到具有匹配的 Export
的类型并调用它们的无参数构造函数,在创建实例后它将查看该类型的 Import
并开始再来一遍。
现在,如果在某个时候它遇到一个 Import
指令,该指令要求一个已经创建的类型,它会将已经存在的实例提供给该 Import
指令 - 而不是创建第二个实例。
您可以通过向一些类型添加无参数构造函数并在其中放置断点来轻松验证这一点。
至于你的第二个问题,我建议问一个单独的问题 - 但据我所知,ComposeParts
将查找或实例化以前未使用/未知的部分和广告调用它的类型/对象的 Export
属性 - 在您的例子中为 [Export(typeof(IHostingForm))]
。另一方面,GetExportedValue
只会搜索已经存在的部分,不会实例化新部分 - 这意味着如果 Import
要求部分 X 但没有此类部分之前由 ComposeParts
或 SatisfyImports
创建 - Import
背后的属性/字段将保持不满足/null
.
关于c# - MEF - 帮助理解容器和组合发生了什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42798441/
这是我想做的 1 - 点击提交 2 - 隐藏 DIV 容器 1 3 - 显示 DIV 容器 2 4 - 将“PricingDisclaimer.php”中找到的所有 DIV 加载到 Div 容器 2
我有一个 ios 应用程序,它使用 iCloudcontainer 来保存用户的一些数据,例如用户的“到期日期”。我要用不同的方式创建应用程序的副本开发者账号。我要将用户从第一个应用程序迁移到第二个应
这是场景。 我有三个容器。 Container1、container2 和 container3(基于 Ubuntu 的镜像),其中 container2 充当容器 1 和容器 2 之间的路由器。 我
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我正在改造管道以使用声明式管道方法,以便我能够 to use Docker images在每个阶段。 目前我有以下工作代码,它执行连接到在 Docker 容器中运行的数据库的集成测试。 node {
我正在开发一个需要尽可能简单地为最终用户安装的应用程序。虽然最终用户可能是经验丰富的 Linux 用户(或销售工程师),但他们对 Tomcat、Jetty 等并不真正了解,我认为他们也不应该了解。 所
我从gvisor-containerd-shim(Shim V1)移到了containerd-shim-runsc-v1(Shim V2)。在使用gvisor-containerd-shim的情况下,
假设我们只在某些开发阶段很少需要这样做(冒烟测试几个 api 调用),让项目 Bar 中的 dockerized web 服务访问 Project Foo 中的 dockerized web 服务的最
各位,我的操作系统是 Windows 10,运行的是 Docker 版本 17.06.0-ce-win19。我在 Windows 容器中运行 SQL Server Express,并且希望将 SQL
谁能告诉我,为什么我们不能在 Azure 存储中的容器内创建容器?还有什么方法可以处理,我们需要在 azure 存储中创建目录层次结构? 最佳答案 您无法在容器中创建容器,因为 Windows Azu
#include template struct Row { Row() { puts("Row default"); } Row(const Row& other) { puts
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
RDF容器用于描述一组事物 例如,把一本书的所有作者列在一起 RDF容器有三种类型: <Bag> <Seq> <Alt> <rdf:
编辑:从到目前为止添加的答案和评论看来,我没有正确解释我想要什么。下面是一个例子: // type not supporting any type of comparison [] [] type b
我正在测试 spatie 的异步项目。我创建了一个这样的任务。 use Spatie\Async\Task; class ServiceTask extends Task { protecte
我想使用 Azure Blob 存储来上传和下载文档。有一些公司可以上传和下载他们的文档。我想保证这些文件的安全。这意味着公司只能看到他们的文件。不是别人的。 我可以在 blob 容器中创建多个文件夹
我正在尝试与 Azure 中的容器实例进行远程交互。我已执行以下步骤: 已在本地注册表中加载本地镜像 docker load -i ima.tar 登录远程 ACR docker登录--用户名--密码
我正在研究http://progrium.viewdocs.io/dokku/process-management/,并试图弄清楚如何从单个项目中运行多个服务。 我有一个Dockerfile的仓库:
我有一个想要容器化的单体应用程序。文件夹结构是这样的: --app | |-file.py <-has a variable foo that is passed in --configs
我正在学习 Docker,并且一直在为 Ubuntu 容器制作 Dockerfile。 我的问题是我不断获取不同容器之间的持久信息。我已经退出,移除了容器,然后移除了它的图像。在对 Dockerfil
我是一名优秀的程序员,十分优秀!