/// <summary> /// Creates the view and the view model /// The view is then registered so that the PaunPacker.GUI could load it later /// </summary> /// <remarks>Implementation of the Prism's <see cref="IModule"/> interface</remarks> /// <param name="containerProvider">Container provider given by the Prism</param> public void OnInitialized(IContainerProvider containerProvider) { IUnityContainer container = containerProvider.Resolve <IUnityContainer>(); var view = new Views.GeneticMinimumBoundingBoxFinderView { DataContext = new ViewModels.GeneticMinimumBoundingBoxFinderViewModel(container) }; container.RegisterInstance <UserControl>(PluginViewWiring.GetViewName(typeof(GeneticMinimumBoundingBoxFinder)), view); }
/// <summary> /// Event handler of the <see cref="ModulesLoadedEvent"/> /// Gets all the <see cref="ISkylineRectAndPointPicker"/> that were loaded by the PaunPacker.GUI and passes them /// to the <see cref="SkylineAlgorithmViewModel"/> so that the user could select it via the view of this plugin /// </summary> /// <param name="payload">The payload of the event</param> private void OnModulesLoaded(ModulesLoadedPayload payload) { var view = new SkylineAlgorithmView() { DataContext = new SkylineAlgorithmViewModel(payload.GetLoadedTypes <ISkylineRectAndPointPicker>() .Concat(unityContainer.Registrations.Select(x => x.RegisteredType).Where(x => typeof(ISkylineRectAndPointPicker).IsAssignableFrom(x) && !x.IsAbstract && !x.IsInterface)) .Distinct(), unityContainer) }; unityContainer.RegisterInstance <UserControl>(PluginViewWiring.GetViewName(typeof(SkylineAlgorithm)), view); }
/// <summary> /// Event handler of the <see cref="ModulesLoadedEvent"/> /// Gets all the Guillotine algorithm's dependencies that were loaded by the PaunPacker.GUI and passes them /// to the <see cref="GuillotineAlgorithmViewModel"/> so that the user could select it via the view of this plugin /// </summary> /// <param name="payload">The payload of the event</param> private void OnModulesLoaded(ModulesLoadedPayload payload) { var view = new GuillotineAlgorithmView() { DataContext = new GuillotineAlgorithmViewModel( payload.GetLoadedTypes <IFreeRectangleExtractor>() .Concat(unityContainer.Registrations.Select(x => x.RegisteredType).Where(x => typeof(IFreeRectangleExtractor).IsAssignableFrom(x) && !x.IsAbstract && !x.IsInterface)), payload.GetLoadedTypes <IFreeRectangleSplitter>() .Concat(unityContainer.Registrations.Select(x => x.RegisteredType).Where(x => typeof(IFreeRectangleSplitter).IsAssignableFrom(x) && !x.IsAbstract && !x.IsInterface)), payload.GetLoadedTypes <IFreeRectangleMerger>() .Concat(unityContainer.Registrations.Select(x => x.RegisteredType).Where(x => typeof(IFreeRectangleMerger).IsAssignableFrom(x) && !x.IsAbstract && !x.IsInterface)), payload.GetLoadedTypes <IRectOrientationSelector>() .Concat(unityContainer.Registrations.Select(x => x.RegisteredType).Where(x => typeof(IRectOrientationSelector).IsAssignableFrom(x) && !x.IsAbstract && !x.IsInterface)), payload.GetLoadedTypes <IFreeRectanglePostProcessor>() .Concat(unityContainer.Registrations.Select(x => x.RegisteredType).Where(x => typeof(IFreeRectanglePostProcessor).IsAssignableFrom(x) && !x.IsAbstract && !x.IsInterface)) .Distinct(), unityContainer) }; unityContainer.RegisterInstance <UserControl>(PluginViewWiring.GetViewName(typeof(GuillotinePlacementAlgorithm)), view); }
/// <summary> /// Performs initialization and exports the types /// </summary> /// <param name="containerProvider">Container provider given by the Prism</param> public void OnInitialized(IContainerProvider containerProvider) { IoC = containerProvider.Resolve <IUnityContainer>(); EventAggregator = containerProvider.Resolve <IEventAggregator>(); //Export simple types that are defined in PaunPacker.Core IoC.RegisterType <HeuristicBackgroundRemover>(); IoC.RegisterType <PowerOfTwoSizePacker>(); IoC.RegisterType <UnknownSizePacker>(); IoC.RegisterFactory <BLAlgorithmPacker>((unityContainer) => { var sorter = unityContainer.Resolve <IImageSorter>(); if (sorter == null) { return(new BLAlgorithmPacker()); } return(new BLAlgorithmPacker(sorter)); }); IoC.RegisterType <MaximalRectanglesAlgorithm>(); IoC.RegisterType <GuillotineBestAreaFitAlgorithm>(); IoC.RegisterType <MaxRectsFreeRectanglePostProcessor>(); IoC.RegisterType <MaxRectsFreeRectangleSortedMerger>(); IoC.RegisterType <MaxRectsFreeRectangleSplitter>(); IoC.RegisterType <ByHeightAndWidthImageSorter>(); IoC.RegisterType <ByHeightAndWidthImageSorterDesc>(); IoC.RegisterType <PreserveOrderImageSorter>(); //FixedSize packers are handled directly from the PaunPacker.GUI (their GUI is MainWindow) //Export types that are accompanied by the GUI //Extruder var extruderView = new ExtruderView() { DataContext = new ExtruderViewModel(IoC) }; //ColorTypeChanger //Trimmer var trimmerView = new TrimmerView() { DataContext = new TrimmerViewModel(IoC) }; //CroppingTrimmer var croppingTrimmerView = new CroppingTrimmerView() { DataContext = new CroppingTrimmerViewModel(IoC) }; //PaddingAdder var paddingAdderView = new PaddingAdderView() { DataContext = new PaddingAdderViewModel(IoC) }; //Register the views IoC.RegisterInstance <UserControl>(PluginViewWiring.GetViewName(typeof(Extruder)), extruderView); IoC.RegisterInstance <UserControl>(PluginViewWiring.GetViewName(typeof(Trimmer)), trimmerView); IoC.RegisterInstance <UserControl>(PluginViewWiring.GetViewName(typeof(CroppingTrimmer)), croppingTrimmerView); IoC.RegisterInstance <UserControl>(PluginViewWiring.GetViewName(typeof(PaddingAdder)), paddingAdderView); }
/// <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(); }