2011-04-11 49 views
4

我有一个对象实例,并且我想最终获得一个包含该对象实例的MEF目录,并将其导出为特定的接口类型。我怎样才能做到这一点?如何将现有实例添加到MEF目录?

TypeCatalog在这里似乎不可行,因为(a)它创建了一个新的实例而不是现有的实例,并且(b)它需要该类型具有[Export]属性。在我的情况下,实例来自MEF的元数据系统,因此MEF创建了基础类型,我无法向其添加属性。

据我所知,通常的建议是,如果你有一个现有的情况下,你应该把它添加到容器(例如,通过CompositionBatch),不给目录。但是当我添加这个实例时,我还添加了整个AssemblyCatalog类型的值,都在同一个操作中。我也希望能够在以后删除所有这些类型。将所有内容捆绑到一个AggregateCatalog中更有意义。这样,我可以在一个原子操作中添加程序集和实例,并且可以以同样的方式再次删除它们。

例如:

// Bootstrapper code to initialize MEF: 
public void Configure() { 
    _selectedGameCatalog = new AggregateCatalog(); 
    var globalCatalog = new AggregateCatalog(_selectedGameCatalog); 
    _container = new CompositionContainer(globalCatalog); 
    // ... more MEF initialization ... 
} 

// Sometime later, I want to add more stuff to the MEF ecosystem: 
public void SelectGame(Lazy<Game, IGameMetadata> entry) { 
    var newCatalog = new AggregateCatalog(); 
    // Make the assembly available to import: 
    newCatalog.Catalogs.Add(new AssemblyCatalog(entry.Value.GetType().Assembly)); 

    // I also want the metadata to be available to import: 
    IGameMetadata metadata = entry.Metadata; 
    newCatalog.Catalogs.Add(MakeCatalogFromInstance<IGameMetadata>(metadata)); 

    // Replace whatever game was selected before: 
    _selectedGameCatalog.Catalogs.Clear(); 
    _selectedGameCatalog.Catalogs.Add(newCatalog); 
} 

我不知道该怎么做的部分是 “MakeCatalogFromInstance”。我如何创建一个包含现有实例的目录(注册为特定类型)?或者,如果我对此有所误解,是否有更好的方法将整个目录一个现有的实例全部同时插入到MEF中,并且能够再次将它们全部拔出后来并用其他东西替换它们?

+0

可能是一个答案http://stackoverflow.com/questions/5191316/adding-an-instance-to-a-mef-container – 2012-11-21 17:54:21

回答

1

我认为最好将类型添加到目录中,然后将实例添加到容器中。

目录包含部分定义。零件定义用于创建零件。 (这种类型是ComposablePartDefinitionComposablePart。)因此,理论上你可以编写自己的目录和零件定义,当调用CreatePart时,它总是返回对应于该实例的零件。但目录并非真的是用这种方式来设计的。

+1

我觉得好生奇怪,MEF将两个完全不同的类声明“这里是获取X的位置”的责任划分了。如果你打算使用它(懒惰初始化),你必须使用目录;如果您打算以另一种方式使用它(现有实例),则必须使用Container。为什么它有这样一个漏洞抽象? – 2011-04-14 15:11:53

1

繁荣......

MEF devivides的是什么类型的信息是从实际运行的对象实例(容器)使用(目录)的琐事。对我而言,这是一个合乎逻辑的决定,特别是当您在应用程序中设置更复杂的MEF环境时。

如果您希望能够随时更改容器,我建议您尝试使用分层容器。根目录/容器中填充了静态类型,任何子容器都可以填充您需要的每种特定元类型。

希望它能帮助, 马克

相关问题