コード例 #1
0
        /// <summary>
        /// Initializes the modules, imports all the types that are exported from the plugins and passes them to the <see cref="MainWindowViewModel"/>
        /// </summary>
        protected override void InitializeModules()
        {
            try
            {
                base.InitializeModules();
            }
            catch (ModularityException e)
            {
                //Error during initialization of some plugin
                //Be verbose so that the user could spot the broken plugin and remove it, for example ..
                var dialogService = Container.Resolve <IDialogService>();
                var dialogParams  = new DialogParameters
                {
                    { MessageDialogParameterNames.Message, e.Message },
                    { MessageDialogParameterNames.Title, "Error" }
                };
                dialogService.ShowDialog("MessageDialogView", dialogParams, (dialogResult) =>
                {
                });
            }

            if (!loadedPlugins.Any(x => x.Assembly.FullName.StartsWith("PaunPacker.Plugins.DefaultImplementationsProviderPlugin,", StringComparison.InvariantCulture)))
            {
                //The default implementations plugin was not loaded
                var dialogService = Container.Resolve <IDialogService>();
                var dialogParams  = new DialogParameters
                {
                    { MessageDialogParameterNames.Message, "Critical error was encountered, the PaunPacker could no run without the plugin with default implementations !" },
                    { MessageDialogParameterNames.Title, "Error" }
                };
                dialogService.ShowDialog("MessageDialogView", dialogParams, (dialogResult) =>
                {
                });
                Shutdown(-1);
            }

            //Assign modules to Shell's ViewModel properly ..
            var mainWindowVM = (MainWindowViewModel)MainWindow.DataContext;

            //Get All instances from mefContainer
            //The reason why only mefContainer is considered here is because unityContainer should be used mainly for
            //factoryRegistrations and dependencies used by these factories are not registered yet
            //On the other hand, MEF is used for easy&fast way to export dependency-less plugins so it is safe to instantiate them at any moment
            var imageSorters              = mefContainer.GetExports <IImageSorter>();
            var placementAlgorithms       = mefContainer.GetExports <IPlacementAlgorithm>();
            var minimumBoundingBoxFinders = mefContainer.GetExports <IMinimumBoundingBoxFinder>();
            var metadataWriters           = mefContainer.GetExports <IMetadataWriter>();
            var imageProcessors           = mefContainer.GetExports <IImageProcessor>();

            //Get All exported types (from both mefContainer & unityContainer)
            var imageSorterTypes = imageSorters.Select(x => x.GetType())
                                   .Concat(FilterUnityExportedTypesByTypeAndAttribute <IImageSorter>(UnityContainer));
            var placementAlgorithmTypes = placementAlgorithms.Select(x => x.GetType())
                                          .Concat(FilterUnityExportedTypesByTypeAndAttribute <IPlacementAlgorithm>(UnityContainer));
            var minimumBoundingBoxFinderTypes = minimumBoundingBoxFinders.Select(x => x.GetType())
                                                .Concat(FilterUnityExportedTypesByTypeAndAttribute <IMinimumBoundingBoxFinder>(UnityContainer));
            var metadataWriterTypes = metadataWriters.Select(x => x.GetType())
                                      .Concat(FilterUnityExportedTypesByTypeAndAttribute <IMetadataWriter>(UnityContainer));
            var imageProcessorTypes = imageProcessors.Select(x => x.GetType())
                                      .Concat(FilterUnityExportedTypesByTypeAndAttribute <IImageProcessor>(UnityContainer));

            mainWindowVM.LoadedPlugins = loadedPlugins
                                         .Concat(mefContainer.GetExports <IMetadataWriter>().Select(x => x.GetType()))
                                         .Concat(mefContainer.GetExports <IImageProcessor>().Select(x => x.GetType()))
                                         .Concat(mefContainer.GetExports <IImageSorter>().Select(x => x.GetType()))
                                         .Concat(mefContainer.GetExports <IPlacementAlgorithm>().Select(x => x.GetType()))
                                         .Concat(mefContainer.GetExports <IMinimumBoundingBoxFinder>().Select(x => x.GetType()))
                                         .Distinct();

            //ExportedTypeMetadataAttribute can be either placed directly on the exported type or on the Plugin Entry point type
            //Obtain all the ExportedTypeMetadataAttributes that are on the Plugin entry points instead of on the actual class being exported
            var exportedMetadataAttributesOnPlugins = mainWindowVM.LoadedPlugins
                                                      .Select(x => x.GetCustomAttributes <ExportedTypeMetadataAttribute>());

            var exportedTypeNameToExportedTypeAttributeMapping = new Dictionary <string, ExportedTypeMetadataAttribute>();

            foreach (var plugin in exportedMetadataAttributesOnPlugins)
            {
                foreach (var exportedType in plugin)
                {
                    exportedTypeNameToExportedTypeAttributeMapping[exportedType.ExportedType.FullName] = exportedType;
                }
            }

            mainWindowVM.ImageSorterVMs = imageSorterTypes
                                          .Distinct()
                                          .Select(x => CreateExportedTypeViewModel(x, exportedTypeNameToExportedTypeAttributeMapping));
            mainWindowVM.PlacementAlgorithmVMs = placementAlgorithmTypes
                                                 .Distinct()
                                                 .Select(x => CreateExportedTypeViewModel(x, exportedTypeNameToExportedTypeAttributeMapping));
            mainWindowVM.MinimumBoundingBoxFinderVMs = minimumBoundingBoxFinderTypes
                                                       .Distinct()
                                                       .Select(x => CreateExportedTypeViewModel(x, exportedTypeNameToExportedTypeAttributeMapping));
            mainWindowVM.MetadataWriterVMs = metadataWriterTypes
                                             .Distinct()
                                             .Select(x => CreateExportedTypeViewModel(x, exportedTypeNameToExportedTypeAttributeMapping));
            mainWindowVM.ImageProcessorVMs = imageProcessorTypes
                                             .Distinct()
                                             .Select(x => CreateExportedTypeViewModel(x, exportedTypeNameToExportedTypeAttributeMapping));

            //The event about modules being loaded is published before view manipulation (because modules could register view in event handler of the modules loaded event)
            var eventAggregator = UnityContainer.Resolve <IEventAggregator>();

            eventAggregator.GetEvent <ModulesLoadedEvent>().Publish(new ModulesLoadedPayload(
                                                                        imageSorterTypes
                                                                        .Concat(placementAlgorithmTypes)
                                                                        .Concat(minimumBoundingBoxFinderTypes)
                                                                        .Concat(metadataWriterTypes)
                                                                        .Concat(imageProcessorTypes)
                                                                        ));

            var regionManager = Container.Resolve <IRegionManager>();

            //Get views for ImageSorters
            var collection = regionManager.Regions[RegionNames.ImageSortersRegion];

            foreach (var imageSorter in mainWindowVM.ImageSorterVMs)
            {
                var view = UnityContainer.Resolve <System.Windows.Controls.UserControl>(PluginViewWiring.GetViewName(imageSorter.ExportedType));
                if (view != null)
                {
                    regionManager.Regions[RegionNames.ImageSortersRegion].Add(view, PluginViewWiring.GetViewName(imageSorter.ExportedType));
                    collection.Deactivate(view);
                }
            }

            //Get views for PlacementAlgorithms, register them and hide all of them
            collection = regionManager.Regions[RegionNames.PlacementAlgorithmsRegion];
            foreach (var placementAlgorithm in mainWindowVM.PlacementAlgorithmVMs)
            {
                var view = UnityContainer.Resolve <System.Windows.Controls.UserControl>(PluginViewWiring.GetViewName(placementAlgorithm.ExportedType));
                if (view != null)
                {
                    regionManager.Regions[RegionNames.PlacementAlgorithmsRegion].Add(view, PluginViewWiring.GetViewName(placementAlgorithm.ExportedType));
                    collection.Deactivate(view);
                }
            }

            //Get views for MinimumBoundingBoxFinders
            collection = regionManager.Regions[RegionNames.MinimumBoundingBoxFinderRegion];
            foreach (var minBoundingBoxFinder in mainWindowVM.MinimumBoundingBoxFinderVMs)
            {
                var view = UnityContainer.Resolve <System.Windows.Controls.UserControl>(PluginViewWiring.GetViewName(minBoundingBoxFinder.ExportedType));
                if (view != null)
                {
                    regionManager.Regions[RegionNames.MinimumBoundingBoxFinderRegion].Add(view, PluginViewWiring.GetViewName(minBoundingBoxFinder.ExportedType));
                    collection.Deactivate(view);
                }
            }


            //Get views for MetadataWriters
            collection = regionManager.Regions[RegionNames.MetadataWritersRegion];
            foreach (var metadataWriter in mainWindowVM.MetadataWriterVMs)
            {
                var view = UnityContainer.Resolve <System.Windows.Controls.UserControl>(PluginViewWiring.GetViewName(metadataWriter.ExportedType));
                if (view != null)
                {
                    regionManager.Regions[RegionNames.MetadataWritersRegion].Add(view, PluginViewWiring.GetViewName(metadataWriter.ExportedType));
                    collection.Deactivate(view);
                }
            }

            //Get views for ImageProcessors
            collection = regionManager.Regions[RegionNames.ImageProcessorsRegion];
            foreach (var imageProcessor in mainWindowVM.ImageProcessorVMs)
            {
                var view = UnityContainer.Resolve <System.Windows.Controls.UserControl>(PluginViewWiring.GetViewName(imageProcessor.ExportedType));
                if (view != null)
                {
                    regionManager.Regions[RegionNames.ImageProcessorsRegion].Add(view, PluginViewWiring.GetViewName(imageProcessor.ExportedType));
                    collection.Deactivate(view);
                }
            }

            mainWindowVM.Initialize();
        }