Guaranteed Order of Imports?

Nov 25, 2008 at 12:00 AM
Hi gang,

Lets say I have an AggregatingComposablePartCatalog which I will be using to load my imported objects.

I add an AttributedAssemblyPartCatalog and then a DirectoryPartCatalog, because I have some "baked in" extensions and I also want users to be able to supply their own in a folder.

Can I guarantee that the "baked in" extensions loaded by the AttributedAssemblyPartCatalog will appear before the user-contributed ones loaded by the DirectoryPartCatalog? For example, if I'm importing them as an IEnumerable<Foo>.

If not, is there a recommended way to guarantee ordering? I suppose I could mark up the inputs with an attribute or custom "order" property and set the baked-in ones to Int32.MinValue, but there's no stopping a plug-in writer from doing the same.

Cheers,
Matt
Coordinator
Nov 25, 2008 at 1:16 AM
There is no way to guarantee the ordering.  Can you explain more about why you would want to do so?  We may be able to provide another way of achieving the same goal.

Thanks,
Daniel
Nov 25, 2008 at 1:21 AM
Sure. I'm planning to use MEF as a way to let people write their own file format converters (in the form of an IFooReader or IFooWriter implementation) that can "plug in" to the Open or Save file dialog.

So the IFooReader defines a few properties (like file extension) and a method like this:

Foo ReadFoo(Stream stream);

My program, then, defines an IEnumerable<IFooReader> as an imported list of add-ins, and displays them in the "list files of type" combobox of the OpenFileDialog when the user opens a file.

The reason I'm interested in ordering is that I'd like for the "baked in" file types to be at the top of the list. The way Excel always keeps .xlsx at the top despite the other file format converters you might have installed.

Like I said, I can easily do this by defining a custom "order" attribute or property, but there's always a way around that (if someone sets the order to Int32.MinValue and the plugin's alphabetical name to AaaFooReader, for example).

Cheers,
Matt
Nov 25, 2008 at 1:30 AM

If it’s an IEnumerable you can simply sort it can you not? If you want to control the ordering that they are returned, you can write a custom ExportProvider (replaces ValueResolver in our next bits) that wraps other providers and sorts them in a specific order.

Glenn

From: mabster [mailto:notifications@codeplex.com]
Sent: Monday, November 24, 2008 6:21 PM
To: Glenn Block
Subject: Re: Guaranteed Order of Imports? [MEF:40694]

From: mabster

Sure. I'm planning to use MEF as a way to let people write their own file format converters (in the form of an IFooReader or IFooWriter implementation) that can "plug in" to the Open or Save file dialog.

So the IFooReader defines a few properties (like file extension) and a method like this:

Foo ReadFoo(Stream stream);

My program, then, defines an IEnumerable<IFooReader> as an imported list of add-ins, and displays them in the "list files of type" combobox of the OpenFileDialog when the user opens a file.

The reason I'm interested in ordering is that I'd like for the "baked in" file types to be at the top of the list. The way Excel always keeps .xlsx at the top despite the other file format converters you might have installed.

Like I said, I can easily do this by defining a custom "order" attribute or property, but there's always a way around that (if someone sets the order to Int32.MinValue and the plugin's alphabetical name to AaaFooReader, for example).

Cheers,
Matt

Read the full discussion online.

To add a post to this discussion, reply to this email (MEF@discussions.codeplex.com)

To start a new discussion for this project, email MEF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Nov 25, 2008 at 1:37 AM
Edited Nov 25, 2008 at 1:38 AM
Ok, I may have to rely on some sort of ordering built into the import either as an attribute or a property.

I'd was looking for a way to tell my host application to "load all the ones in this assembly first, then all the ones you discover in this folder after that", so that add-in writers couldn't provide an order that forces their file extension up above mine in the list, making it the default.

I guess I'm going to have to have my host application "know" what the default file format is and always put it first.

From: [email removed]
Sent: Tuesday, November 25, 2008 1:30 PM
To: [email removed]
Subject: Re: Guaranteed Order of Imports? [MEF:40694]

From: gblock

If it’s an IEnumerable you can simply sort it can you not? If you want to control the ordering that they are returned, you can write a custom ExportProvider (replaces ValueResolver in our next bits) that wraps other providers and sorts them in a specific order.

Glenn

Nov 25, 2008 at 1:48 AM

You can do that in one of two ways. First you can create a custom export provider as I mentioned. Second you can use the new Aggregating Export Provider model (about to ship). The AEP uses a prioritization scheme where export providers at the top of the list take priority over those at the bottom of the list. So, for each file extension that you want, you can create a directory part catalog (it allows passing a filter). Then you can create a different ComposablePartCatalogExportProvider (also new) for each catalog. Once you have the export providers you can add them to an Aggregating Export Provider in whatever order you want. Finally the AEP is passed to the container when it is constructed. Now, whenever the container is queried or it composes, it will return the exports in order of the Export providers within.

From: mabster [mailto:notifications@codeplex.com]
Sent: Monday, November 24, 2008 6:38 PM
To: Glenn Block
Subject: Re: Guaranteed Order of Imports? [MEF:40694]

From: mabster

Ok, I may have to rely on some sort of ordering built into the import either as an attribute or a property.

I'd was looking for a way to tell my host application to "load all the ones in this assembly first, then all the ones you discover in this folder after that", so that add-in writers couldn't provide an order that forces their file extension up above mine in the list, making it the default.

I guess I'm going to have to have my host application "know" what the default file format is and always put it first.

From: [email removed]

Sent: Tuesday, November 25, 2008 1:30 PM

To: [email removed]

Subject: Re: Guaranteed Order of Imports? [MEF:40694]

From: gblock

If it’s an IEnumerable you can simply sort it can you not? If you want to control the ordering that they are returned, you can write a custom ExportProvider (replaces ValueResolver in our next bits) that wraps other providers and sorts them in a specific order.

Glenn

From: mabster [mailto:notifications@codeplex.com]
Sent: Monday, November 24, 2008 6:21 PM
To: Glenn Block
Subject: Re: Guaranteed Order of Imports? [MEF:40694]

From: mabster

Sure. I'm planning to use MEF as a way to let people write their own file format converters (in the form of an IFooReader or IFooWriter implementation) that can "plug in" to the Open or Save file dialog.

So the IFooReader defines a few properties (like file extension) and a method like this:

Foo ReadFoo(Stream stream);

My program, then, defines an IEnumerable<IFooReader> as an imported list of add-ins, and displays them in the "list files of type" combobox of the OpenFileDialog when the user opens a file.

The reason I'm interested in ordering is that I'd like for the "baked in" file types to be at the top of the list. The way Excel always keeps .xlsx at the top despite the other file format converters you might have installed.

Like I said, I can easily do this by defining a custom "order" attribute or property, but there's always a way around that (if someone sets the order to Int32.MinValue and the plugin's alphabetical name to AaaFooReader, for example).

Cheers,
Matt

Read the full discussion online.

To add a post to this discussion, reply to this email (MEF@discussions.codeplex.com)

To start a new discussion for this project, email MEF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Nov 25, 2008 at 2:05 AM
Edited Nov 25, 2008 at 2:09 AM
Ok - that sounds interesting. I'll keep an eye out for the next drop. Thanks Glenn.

I wrote up a quick test this afternoon to see how the existing code works, and so far I have noticed that the order in which exports are "imported" changes depending on the order in which I add my catalogs to my AggregatingComposablePartCatalog. So if I do this:

var asmCatalog = new AttributedAssemblyPartCatalog(typeof(DefaultFooReader).Assembly);
var dirCatalog = new DirectoryPartCatalog(@"..\..\..\ClassLibrary2\bin\Debug");
var catalog = new AggregatingComposablePartCatalog();

catalog.Catalogs.Add(asmCatalog);
catalog.Catalogs.Add(dirCatalog);


... then the exports from asmCatalog appear in my imported IEnumerable<IFooReader> before the exports from dirCatalog. However, if I swap those last two lines around, like this:


catalog.Catalogs.Add(dirCatalog);
catalog.Catalogs.Add(asmCatalog);


... then the dirCatalog exports appear first.

That's definitely the behavior I want, but I guess it's not guaranteed.

Matt

From: [email removed]
Sent: Tuesday, November 25, 2008 1:48 PM
To: [email removed]
Subject: Re: Guaranteed Order of Imports? [MEF:40694]

From: gblock

You can do that in one of two ways. First you can create a custom export provider as I mentioned. Second you can use the new Aggregating Export Provider model (about to ship). The AEP uses a prioritization scheme where export providers at the top of the list take priority over those at the bottom of the list. So, for each file extension that you want, you can create a directory part catalog (it allows passing a filter). Then you can create a different ComposablePartCatalogExportProvider (also new) for each catalog. Once you have the export providers you can add them to an Aggregating Export Provider in whatever order you want. Finally the AEP is passed to the container when it is constructed. Now, whenever the container is queried or it composes, it will return the exports in order of the Export providers within.

 

Nov 25, 2008 at 2:38 AM
Actually the aggregating catalog does inherently query in order of the catalog list, so it is probably ok.

Glenn

-----Original Message-----
From: "mabster" <notifications@codeplex.com>
To: "Glenn Block" <gblock@microsoft.com>
Sent: 11/24/2008 7:06 PM
Subject: Re: Guaranteed Order of Imports? [MEF:40694]

From: mabster

Ok - that sounds interesting. I'll keep an eye out for the next drop. Thanks Glenn.
I wrote up a quick test this afternoon to see how the existing code works, and so far I have noticed that the order in which exports are "imported" changes depending on the order in which I add my catalogs to my AggregatingComposablePartCatalog. So if I do this:
var asmCatalog = new AttributedAssemblyPartCatalog(typeof(DefaultFooReader).Assembly);
var dirCatalog = new DirectoryPartCatalog(@"..\..\..\ClassLibrary2\bin\Debug");
var catalog = new AggregatingComposablePartCatalog();

catalog.Catalogs.Add(asmCatalog);
catalog.Catalogs.Add(dirCatalog);
... then the exports from asmCatalog appear in my imported IEnumerable<IFooReader> before the exports from dirCatalog. However, if I swap those last two lines around, like this:
catalog.Catalogs.Add(dirCatalog);
catalog.Catalogs.Add(asmCatalog);
... then the dirCatalog exports appear first.
That's definitely the behavior I want, but I guess it's not guaranteed.
Matt

From: [email removed]
Sent: Tuesday, November 25, 2008 1:48 PM
To: [email removed]
Subject: Re: Guaranteed Order of Imports? [MEF:40694]

From: gblock

You can do that in one of two ways. First you can create a custom export provider as I mentioned. Second you can use the new Aggregating Export Provider model (about to ship). The AEP uses a prioritization scheme where export providers at the top of the list take priority over those at the bottom of the list. So, for each file extension that you want, you can create a directory part catalog (it allows passing a filter). Then you can create a different ComposablePartCatalogExportProvider (also new) for each catalog. Once you have the export providers you can add them to an Aggregating Export Provider in whatever order you want. Finally the AEP is passed to the container when it is constructed. Now, whenever the container is queried or it composes, it will return the exports in order of the Export providers within.

Nov 25, 2008 at 2:41 AM
The advantage the aggregating export provider had that catalogs don't is that you can use the AEP to establish overridable semantics. For example a default logger that is overridden.

Glenn



-----Original Message-----
From: "mabster" <notifications@codeplex.com>
To: "Glenn Block" <gblock@microsoft.com>
Sent: 11/24/2008 7:06 PM
Subject: Re: Guaranteed Order of Imports? [MEF:40694]

From: mabster

Ok - that sounds interesting. I'll keep an eye out for the next drop. Thanks Glenn.
I wrote up a quick test this afternoon to see how the existing code works, and so far I have noticed that the order in which exports are "imported" changes depending on the order in which I add my catalogs to my AggregatingComposablePartCatalog. So if I do this:
var asmCatalog = new AttributedAssemblyPartCatalog(typeof(DefaultFooReader).Assembly);
var dirCatalog = new DirectoryPartCatalog(@"..\..\..\ClassLibrary2\bin\Debug");
var catalog = new AggregatingComposablePartCatalog();

catalog.Catalogs.Add(asmCatalog);
catalog.Catalogs.Add(dirCatalog);
... then the exports from asmCatalog appear in my imported IEnumerable<IFooReader> before the exports from dirCatalog. However, if I swap those last two lines around, like this:
catalog.Catalogs.Add(dirCatalog);
catalog.Catalogs.Add(asmCatalog);
... then the dirCatalog exports appear first.
That's definitely the behavior I want, but I guess it's not guaranteed.
Matt

From: [email removed]
Sent: Tuesday, November 25, 2008 1:48 PM
To: [email removed]
Subject: Re: Guaranteed Order of Imports? [MEF:40694]

From: gblock

You can do that in one of two ways. First you can create a custom export provider as I mentioned. Second you can use the new Aggregating Export Provider model (about to ship). The AEP uses a prioritization scheme where export providers at the top of the list take priority over those at the bottom of the list. So, for each file extension that you want, you can create a directory part catalog (it allows passing a filter). Then you can create a different ComposablePartCatalogExportProvider (also new) for each catalog. Once you have the export providers you can add them to an Aggregating Export Provider in whatever order you want. Finally the AEP is passed to the container when it is constructed. Now, whenever the container is queried or it composes, it will return the exports in order of the Export providers within.