ImportMany ExportUIVisualizer Issue

Nov 28, 2011 at 1:43 AM

Hi,

I cannot get any window in the TestMvvmApp (or any other app I make for that matter) to register to the UIVisualizer using the ExportUIVisualizer attribute.

If I simply run the TestMvvmApp in the source, the properties window does not open for example. If I debug the app, I find that the _locatedVisuals is empty, which I am assuming means the ImportMany was unsuccessful? Any ideas would be greatly appreciated. Does TestMvvmApp work for you? As I am testing the code unedited.

Matt

Nov 28, 2011 at 12:54 PM

Ok. I figured out that the problem is with the "AllowMultiple = true" in the AttributeUsage attribute of the ExportUIVisualizerAttribute.

The problem is that the attribute still uses the IUIVisualizerMetaData which does not contain an ARRAY of Keys (and so won't match the AllowMultiple results).

Personally I don't see why you want AllowMultiple to be true, as why would you want to give a view multiple keys? If you still want to for what ever reason, you need to redefine how the UIVisualizer registration will work, particularly when multiple keys are applied (do you simply register it multiple times using different keys?)

Anway I made the changes at my end if you want to include them do the following:

1. Copy the IUIVisualizerMetadata class and make a IUIVisualizerMetaDataMultiple class where the the keys are an array "string[] Key { get; }"

    /// <summary>
    /// Interface used to populate metadata we use for services (multiple being true).
    /// </summary>
    public interface IUIVisualizerMetadataMultiple
    {
        /// <summary>
        /// Key used to export the UI - registered with the UIVisualizer.
        /// </summary>
        string[] Key { get; }
 
        /// <summary>
        /// The type being exported
        /// </summary>
        string ExportTypeIdentity { get; }
    }

2. Update the UIVisualizer ImportMany call to use the new metadata interface from above.

private IEnumerable<Lazy<objectIUIVisualizerMetadataMultiple>> _locatedVisuals;

3. Replace the CheckForDynamicRegisters() with:

/// <summary>
/// Initialize any MEF-located views.
/// </summary>
private void CheckForDynamicRegisters()
{
    if (!_haveLoadedVisuals) {
        // If we have visuals, register them
        foreach (var item in _locatedVisuals) {
            Type type = FindType(item.Metadata.ExportTypeIdentity);
            if (type != null) {
               foreach (string sKey in item.Metadata.Key) {
                   Register(sKey, type);
               }
            }
        }
 
        // Clear the collection so we don't process twice.
        _haveLoadedVisuals = true;
    }
}
Nov 28, 2011 at 1:04 PM

Just added a patch.

Coordinator
Dec 27, 2011 at 6:46 PM

Hi Matt,

Yes, I ran into the same issue -- we added the AllowMultiple to support a special case, but when I hit this issue, I felt it was too obscure to really benefit anyone so I removed it with 4.07.  I may look at your patch and include it in a future version - thanks for the update!

 

Coordinator
Feb 21, 2012 at 12:37 AM

This has been corrected in 4.08 - thanks Matt!  There is a sample project you can download to test it as well - see the Downloads area.