Efficient Scoping in MEF2

Nov 23, 2011 at 8:56 PM

Hello,

I am moving an application framework over to MEF2. I make heavy use of scoping - I have a hierarchy of scopes, 3-4 levels deep with dozen of different contents (first level application, second modules, every module has other subelements).

In my own MEF1 implementation I use one catalog that i then filter further.

it seems in MEF2 the approach requires me to build dozen of different catalogs everytime with a different builder FROM THE ASSEMBLIES. Is that not inefficient?

Would not be better to have:

* One catalog with one registration builder for the "base catalog". This will be very broad.

* Sub-cttalogs created from the main catalog with additional builders?

The idea is that the assmeblies dont need to be rescanned all the time completely.

Nov 23, 2011 at 9:02 PM

Hi,

No, in MEF 2 the CompositionScopeDefinition mechanism also works off of filtered catalogs. Can you post some more details of your catalog setup, e.g. for one level deep? I’ll see if I can translate to CSD terms.

Regards,
Nick

From: NetTecture [email removed]
Sent: Wednesday, November 23, 2011 12:57 PM
To: Nicholas Blumhardt
Subject: Efficient Scoping in MEF2 [MEF:280636]

From: NetTecture

Hello,

I am moving an application framework over to MEF2. I make heavy use of scoping - I have a hierarchy of scopes, 3-4 levels deep with dozen of different contents (first level application, second modules, every module has other subelements).

In my own MEF1 implementation I use one catalog that i then filter further.

it seems in MEF2 the approach requires me to build dozen of different catalogs everytime with a different builder FROM THE ASSEMBLIES. Is that not inefficient?

Would not be better to have:

* One catalog with one registration builder for the "base catalog". This will be very broad.

* Sub-cttalogs created from the main catalog with additional builders?

The idea is that the assmeblies dont need to be rescanned all the time completely.

Nov 23, 2011 at 9:05 PM

Lovely.

ok, First level lives in an  Application object. It has the root CompositionContainer and also the full catalog.

Second level is MODULE (inherits from Module and is not abstract). It has a IPartImportsSatisfiedNotification and wen triggered it will need to create a filtered sub composition container that contains all elements that are defined for itself as parent (attribute or another metchanis m - I use a PartMetaData "Scope" here so far). It has the root CompositionContainer as parent.

Third level is similar.

;) Any idea? I love the idea of scopeing off a catalog. But the FilteredCatalog is manual, right? it is not in there yet?

Nov 23, 2011 at 9:30 PM

No, Filter() is there in the “Hosting” namespace.

I’m not as familiar with this functionality as others on the MEF project team, so there may be simpler ways to achieve this and if so hopefully someone will chime in.

There are a lot of moving parts – ExportFactory for example comes into the picture – but here’s a sketch that might get you started:

var catalog = new DirectoryCatalog(“…”); // Any catalog

var unbound = catalog.Filter(p => !p.MetadataContainsKey(“Scope”));

var app = unbound.Complement.Filter(p => p.Metadata[“Scope”] == “Application”);

var mod = unbound.Complement.Filter(p => p.Metadata[“Scope”] == “Module”);

var scopes = new CompositionScopeDefinition(new AggregateCatalog(app, unbound), new[] {

new CompositionScopeDefinition(new AggregateCatalog(mod, unbound), null)
});

var container = new CompositionContainer(scopes);

From that point, assuming the application object is in the root scope:

[PartMetadata(“Scope”, “Application”), Export]

public class Application

{

[ImportingConstructor]

public Application(ExportFactory<Module> moduleFactory) { … }
}

And Module is tagged with Module scope:

[PartMetadata(“Scope”, “Module”), Export]

public class Module { … }

Then just get the top level from the container:

var application = container.GetExportedValue<Application>();

The application object can begin/end module level scopes by creating modules with the injected ExportFactory.

Any dependencies of either type that are not tagged with a scope will be injected; applying the scope metadata to other parts will control their scope.

Again, this is quite new to me J so I’ll be very interested to hear your thoughts and experiences with it.

Cheers,
Nick

From: NetTecture [email removed]
Sent: Wednesday, November 23, 2011 1:06 PM
To: Nicholas Blumhardt
Subject: Re: Efficient Scoping in MEF2 [MEF:280636]

From: NetTecture

Lovely.

ok, First level lives in an Application object. It has the root CompositionContainer and also the full catalog.

Second level is MODULE (inherits from Module and is not abstract). It has a IPartImportsSatisfiedNotification and wen triggered it will need to create a filtered sub composition container that contains all elements that are defined for itself as parent (attribute or another metchanis m - I use a PartMetaData "Scope" here so far). It has the root CompositionContainer as parent.

Third level is similar.

;) Any idea? I love the idea of scopeing off a catalog. But the FilteredCatalog is manual, right? it is not in there yet?

Dec 6, 2011 at 9:42 PM

Reacting it now as I try to get it working ;9

This looks exclusive, at least it is on my end.

I can not get the unbound.Complement.Filter part working ;(

var unbound = compositionCatalog.Filter(p => !p.ContainsPartMetadataWithKey("Scope"));

works perfectly. I get the not marked stuff in unbound and the other elements are in the corresponding Complement property. The line

var application = unbound.Complement.Filter(p => p.Metadata["Scope"] == "Application");

then just returns an empty collection, although I can see the scope in the Metadata (the only element with PartsMetaData.

Also, as I try to move away from the PartsMetaData - is there an easy way to filter by inheritance? Especially as "Module" is a base class, and I try o work without the attributes, which also means no PartsMetaData... I want to use inheritance here.

And finally:

            var scopes = new CompositionScopeDefinition(
                new AggregateCatalog(application, unbound), new[] {
                new CompositionScopeDefinition(new AggregateCatalog(module, unbound), null)
            });

I can not make any sense out of that. Why is "unbound" mentioned multiple times? Any clearer example? ;)

Slowly making my way into it, though. Now that finally I find the time to work on things.

 

Jun 5, 2013 at 4:58 PM