Preview 5: How to qualify the import?

Apr 28, 2009 at 11:44 AM
Now that ImportRequiresMetaData has been apparently removed (or if I'm just failing to find it, consider that it's planned to be removed), how do I qualify the import of a property on a part?

I have a set of application components but I am completely decoupling the processing engine from the user interface which controls that engine. Thus, let's say I have the following components (both with a shared creation policy):
  • ProjectManager
  • SettingsManager
And then I have the following user interface components
  • ProjectManagerUI
  • SettingsManagerUI
I want ProjectManagerUI to import ProjectManager as a property and therefore I need to qualify it statically in the import. I could do it dynamically, but that seems like a roundabout way of doing things when the engine should provide some sort of qualifying mechnism which allows greater filtering than simply the contract name and type.

Perhaps someone could update the documentation? It's kind of hard to figure some things out when all the explanations and samples explain how to do things based on deprecated features.
Apr 28, 2009 at 12:52 PM

Hi Nathan,

It sounds as though ProjectManager and SettingsManager should have different contracts. I.e. in ProjectManagerUI (according to your description) it seems like:

[Import]

public ProjectManager ProjectManager { get; set; }

..would suffice.

In the SettingsManagerUI you’d use:

[Import]

public SettingsManager SettingsManager { get; set; }

Did I understand you correctly?

In cases that you do require import metadata you can use the Export<T, TMetadata> type for imported members. Check out the usage of the IToolboxItemMetadataView type in the MEFStudio sample included with the latest MEF drop.

Thanks for the feedback.

Nick

From: NathanRidley [mailto:notifications@codeplex.com]
Sent: Tuesday, April 28, 2009 4:45 AM
To: Nicholas Blumhardt
Subject: Preview 5: How to qualify the import? [MEF:54706]

From: NathanRidley

Now that ImportRequiresMetaData has been apparently removed (or if I'm just failing to find it, consider that it's planned to be removed), how do I qualify the import of a property on a part?

I have a set of application components but I am completely decoupling the processing engine from the user interface which controls that engine. Thus, let's say I have the following components (both with a shared creation policy):

  • ProjectManager
  • SettingsManager

And then I have the following user interface components

  • ProjectManagerUI
  • SettingsManagerUI

I want ProjectManagerUI to import ProjectManager as a property and therefore I need to qualify it statically in the import. I could do it dynamically, but that seems like a roundabout way of doing things when the engine should provide some sort of qualifying mechnism which allows greater filtering than simply the contract name and type.

Perhaps someone could update the documentation? It's kind of hard to figure some things out when all the explanations and samples explain how to do things based on deprecated features.

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

Apr 28, 2009 at 1:02 PM
Edited Apr 28, 2009 at 1:04 PM
I used ProjectManager and SettingsManager as examples but really there could be any number of components. They are all members of the contract IApplicationComponent which is basically a high level feature of the application. Each of these components is loaded and initialized at the start via methods defined in IApplicationComponent.

The whole application is being designed to run without a user interface, but in a secondary assembly I'm providing all of the parts required to build a user interface around the various application components. Therefore whilst the overall application doesn't care to make a distinction between the different components (hence the single unified contract), each of the user interface parts does care which component it's talking to and thus needs to qualify the component it controls.

Those user interface parts are still required to be exports though, as I may build additional features and simply plug them in along with the other application components, and those features will need to exist without a user interface but also be accompanied by a user interface component that controls that component.

I do not want the user interface code to be hardcoded with the engine code for each component.
Apr 28, 2009 at 1:05 PM

I guess the next question I’d ask then is: how do the user interface components interact with the ‘engine’ components that they depend upon? Do they cast them to a different interface?

Cheers,

Nick

From: NathanRidley [mailto:notifications@codeplex.com]
Sent: Tuesday, April 28, 2009 6:02 AM
To: Nicholas Blumhardt
Subject: Re: Preview 5: How to qualify the import? [MEF:54706]

From: NathanRidley

I used ProjectManager and SettingsManager as examples but really there could be any number of components. They are all members of the contract IApplicationComponent which is basically a high level feature of the application. Each of these components is loaded and initialized at the start via methods defined in IApplicationComponent. The whole application is being designed to run without a user interface, but in a secondary assembly I'm providing all of the parts required to build a user interface around the various application components. Therefore whilst the overall application doesn't care to make a distinction between the different components (hence the single unified contract), each of the user interface parts does care which component it's talking to and thus needs to qualify the component it controls. Those user interface parts are still required to be exports though, as I may build additional features and simply plug them in along with the other application components, and those features will need to exist without a user interface but also be accompanied by a user interface component that controls that component.

I do not want the user interface code to be hardcoded with the engine code for each component.

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

Apr 28, 2009 at 1:12 PM
Assuming:

[ExportMetadata("ApplicationComponent.ID", "ProjectManager")]
class ProjectManager : IApplicationComponent
...

I'd qualify on the "ApplicationComponent.ID" MetaData key, getting back a single IApplicationComponent (hopefully). I'd then cast that back to ProjectManager and start interacting with it via its own unique methods.

I'm open to a better way to approach the problem if you have one, but it is important that the user interface parts are exports so that they can import their own dependencies, properties, etc, and that whilst the user interface parts are dependent on the specific component(s) they control, the components are entirely independent of the user interface parts.
Apr 28, 2009 at 1:19 PM

I think the key piece of MEF functionality you’re missing is the ability for a single part to export multiple contracts. E.g.:

                [Export(typeof(ProjectManager)]

[Export(typeof(IApplicationComponent)]

[…]

public class ProjectManager : IApplicationComponent

This means that your non-UI parts can access the application components as they probably do now:

                [Import]

                public IEnumerable<IApplicationComponent> AppComponents { get; set; }

Neither the part nor the consumer in this case has any UI dependency.

The UI on the other hand uses the style of import I showed in this thread already:

                [Import]

                public ProjectManager ProjectManager { get; set; }

Since the UI already casts to ProjectManager there is no additional coupling created by this import.

If ProjectManager has Shared creation policy then both of its exports (IApplicationService and ProjectManager) will point to the same instance.

The multiple IApplicationComponents imported into the ‘startup’ component will include an instance each of ProjectManager, SettingsManager, etc.

Does this solve your case?

Cheers,
Nick

From: NathanRidley [mailto:notifications@codeplex.com]
Sent: Tuesday, April 28, 2009 6:12 AM
To: Nicholas Blumhardt
Subject: Re: Preview 5: How to qualify the import? [MEF:54706]

From: NathanRidley

Assuming:

[ExportMetadata("ApplicationComponent.ID", "ProjectManager")]

class ProjectManager : IApplicationComponent

...

I'd qualify on the "ApplicationComponent.ID" MetaData key, getting back a single IApplicationComponent (hopefully). I'd then cast that back to ProjectManager and start interacting with it via its own unique methods.

I'm open to a better way to approach the problem if you have one, but it is important that the user interface parts are exports so that they can import their own dependencies, properties, etc, and that whilst the user interface parts are dependent on the specific component(s) they control, the components are entirely independent of the user interface parts.

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

Apr 28, 2009 at 1:23 PM
That absolutely solves my problem, thankyou! I must have overlooked the part in the documentation where it talked about multiple export contracts in a single class. Thanks again.
Apr 28, 2009 at 1:25 PM

You’re welcome. The documentation is still a work-in-progress, this aspect could be missing. We’ll make sure that this appears in the RTM docs.

Nick

From: NathanRidley [mailto:notifications@codeplex.com]
Sent: Tuesday, April 28, 2009 6:23 AM
To: Nicholas Blumhardt
Subject: Re: Preview 5: How to qualify the import? [MEF:54706]

From: NathanRidley

That absolutely solves my problem, thankyou! I must have overlooked the part in the documentation where it talked about multiple export contracts in a single class. Thanks again.

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