开发者

MEF InheritedExport hiding?

Apologies for the vague question framing.

Here is the situation. I have ParentA in Assembly1( class library). ParentA exports typeof ParentA

Now another product team wants to override some of the behaviour of ParentA, in ChildA and deploy their Assembly - Assembly2, which holds a reference to Assembly1 (obviously).

The requriement is that ParentA is comp开发者_如何转开发letely hidden by ChildA and all containers that import ParentA should now get a reference to an instance of ChildA instead. Standard Inheritance stuff.

BUT - Would MEF export instances of both ParentA AND ChildA?

How would i work around this situation ?


Perhaps this is what you are / were looking for:

http://msdn.microsoft.com/en-us/library/ee155691.aspx#avoiding_discovery

This is what it says:

In some cases, you may want to prevent a part from being discovered as part of a catalog. For example, the part may be a base class intended to be inherited from, but not used. There are two ways to accomplish this. First, you can use the abstract keyword on the part class. Abstract classes never provide exports, although they can provide inherited exports to classes that derive from them.

If the class cannot be made abstract, you can decorate it with the PartNotDiscoverable attribute. A part decorated with this attribute will not be included in any catalogs. The following example demonstrates these patterns. DataOne will be discovered by the catalog. Since DataTwo is abstract, it will not be discovered. Since DataThree used the PartNotDiscoverable attribute, it will not be discovered.

<Export()>
Public Class DataOne
    'This part will be discovered 
    'as normal by the catalog.
End Class

<Export()>
Public MustInherit Class DataTwo
    'This part will not be discovered
    'by the catalog.
End Class

<PartNotDiscoverable()>
<Export()>
Public Class DataThree
    'This part will also not be discovered
    'by the catalog.
End Class


When MEF finds two exports for ClassA when it only expects one, it will throw a CompositionException saying that there is a cardinality problem. It doesn't know how to choose between both.

There is a way around this: if you pass multiple export providers to a container, the container will query each export provider in turn when it looks for an export. The first export provider to provide the part, wins.

In the following example the exports provided by assemblies in the "customized" subfolder override the exports provided by assemblies in the executable's folder.

var defaultExportProvider = 
    new CatalogExportProvider(new DirectoryCatalog(".","*"));
var customizedExportProvider = 
    new CatalogExportProvider(new DirectoryCatalog(@".\customized"));
var container = new CompositionContainer(
    customizedExportProvider, defaultExportProvider);
defaultExportProvider.SourceProvider = container;
customizedExportProvider.SourceProvider = container;

edit:

Since the described solution isn't satisfactory, I can only assume that you are using ImportMany rather than Import. In that case you would indeed still get both exports, and you will have to add some metadata on them. You can then write code in your importing class which decides which import is the "best". See also this blog post by Daniel Plaisted.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜