gpt4 book ai didi

c# - 如何从 MEF 导入创建新对象

转载 作者:行者123 更新时间:2023-11-30 13:02:39 26 4
gpt4 key购买 nike

我对 MEF 有点困惑,我以为我已经开始理解它了,但似乎我还没有完全理解。

因此,我有一个要读入的 XML 测试步骤列表。这个想法是主应用程序在运行时对类型一无所知。

<TestSteps>
<TestRunner xsi:type="SimulateDc" Measurement="54"/>
<TestRunner xsi:type="MeasureDc" Output="1"/>
</TestSteps>

所以我有一个带有静态“结果”类的基类型,它允许我保存信息以在步骤之间传递(上面 XML 中的 Output 属性)。这里的测试处理程序由 MEF 导出,我在运行时读取它们,然后获取 Type 以传递到 XML 序列化程序以创建处理程序列表。这一切都有效,我得到了一个测试运行者列表。我在这里为每种类型都有一个 DataTemplate 导出,所以当我使用内容控件时,它知道如何绘制自己。一切似乎都很好,但我认为我的思考过程出了问题。

一个问题是我现在想将导入的处理程序绑定(bind)到某些硬件。硬件处理例程旨在由更多 MEF 导入处理

所以有了这样的界面:

public interface IMeasureHW
{
double Measure();
}

然后使用这个:

[Export("MeasureDc", typeof(IMeasureHW))]
public class MeasureDcHW : IMeasureHW
{
public double Measure()
{
return 54.0;
}
}

然后在我的一个测试处理程序中我这样做了:

[Import("MeasureDc", typeof(IMeasureHW))]
IMeasureHW hardware { get; set; }

我的导入是这样进行的:

protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog("."));
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));

_container = new CompositionContainer(catalog);

_container.ComposeParts(this);

MainWindow.Show();
}

但是,我猜测上面的 XML 序列化和像我一样使用 Type 信息肯定意味着导入将是空的,这意味着我的设计思维模式是错误的。

我确实设法通过导出 CompositionContainer 让它工作,然后在加载 XML 之后我能够做到这一点:

foreach (TestRunnerBase t in testSteps)
{
_container.SatisfyImportsOnce(t);
}

但这对我来说感觉有点不对劲,因为导入的测试步骤的初始列表除了获取类型外没有用于任何其他用途。所以我在想,我应该将数据导出为 MEF 部分,然后独立导出处理程序,然后当我从 XML 中读取数据列表时,我以某种方式从列表中请求处理程序?如果这有意义?

我不知道如何以这种方式将它们结合在一起,因为 MEF 组合全部在我的 App.xaml.cs 中处理,而测试步骤在其他地方的 View 模型中。我在考虑使用元数据将数据绑定(bind)到处理程序,然后在导入列表中找到相应的处理程序。也许我应该进行初始解析以构建字典以加快查找速度?

这更应该是这样吗?感谢任何帮助,我的头发部门已经很轻了,所以我不能失去更多

最佳答案

如果我错了,请纠正我 - 似乎您可以通过链接导入来实现您的目标:最里面是您的 TestRunner 集合,然后是硬件类,最后是内容控制。

在下面的示例中,它们分别是 Class2 : MySubInterfaceClass1 : MyInterfaceProgram:

/////inner

using MyHostingNamespace;
namespace ClassLibrary1
{


[Export("class2", typeof(MySubInterface))]
class Class2 : MySubInterface
{
public string MyProperty { get; set; }

public Class2()
{

MyProperty = "Class2";
}
}
}

////middle

using MyHostingNamespace;
namespace ClassLibrary1
{


[Export("class1", typeof(MyInterface))]
public class Class1 : MyInterface
{
[Import("class2", AllowDefault=true)]
MySubInterface myClass2;

public string MyProperty {get;set;}

public Class1()
{

AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
CompositionContainer _container = new CompositionContainer(catalog);
_container.ComposeParts(this);

MyProperty = myClass2.MyProperty;
}
}
}

////outer

namespace MyHostingNamespace
{
class Program
{
[Import("class1")]
public MyInterface class1;

public Program()
{
AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
catalog.Catalogs.Add(new DirectoryCatalog("."));
CompositionContainer _container = new CompositionContainer(catalog);

_container.ComposeParts(this);

}

static void Main(string[] args)
{

Program p = new Program();

Console.WriteLine(p.class1.MyProperty);

}

}



public interface MyInterface
{
string MyProperty { get; set; }
}

public interface MySubInterface
{
string MyProperty { get; set; }
}
}

关于c# - 如何从 MEF 导入创建新对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14832072/

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