Пример #1
0
        private void ConfigureContainer(IProgress <string> progress)
        {
            kernel.Bind <ICommandLineArgs>().ToConstant(commandLineArgs).InSingletonScope();

            // use single logger for whole application
            kernel.Bind <Logger>().ToSelf().InSingletonScope();
            kernel.Get <Logger>();

            Debug.WriteLine($"Starting Astrarium {FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion}");

            kernel.Bind <ISettings, Settings>().To <Settings>().InSingletonScope();

            kernel.Bind <ISky, Sky>().To <Sky>().InSingletonScope();
            kernel.Bind <ISkyMap, SkyMap>().To <SkyMap>().InSingletonScope();

            kernel.Bind <UIElementsIntegration>().ToSelf().InSingletonScope();
            UIElementsIntegration uiIntegration = kernel.Get <UIElementsIntegration>();

            ICollection <AbstractPlugin> plugins = new List <AbstractPlugin>();

            string homeFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            IEnumerable <string> pluginPaths = Directory.EnumerateFiles(homeFolder, "Astrarium.Plugins.*.dll", SearchOption.AllDirectories);

            progress.Report("Loading plugins");

            foreach (string path in pluginPaths)
            {
                try
                {
                    var plugin = Assembly.UnsafeLoadFrom(path);
                    Debug.WriteLine($"Loaded plugin {plugin.FullName}");
                }
                catch (Exception ex)
                {
                    Trace.TraceError($"Unable to load plugin assembly with path {path}. {ex})");
                }
            }

            // collect all plugins implementations
            Type[] pluginTypes = AppDomain.CurrentDomain.GetAssemblies()
                                 .SelectMany(a => a.GetTypes())
                                 .Where(t => typeof(AbstractPlugin).IsAssignableFrom(t) && !t.IsAbstract)
                                 .ToArray();

            // collect all calculators types
            Type[] calcTypes = pluginTypes
                               .SelectMany(p => GetCalculators(p))
                               .ToArray();

            foreach (Type calcType in calcTypes)
            {
                var types = new[] { calcType }.Concat(calcType.GetInterfaces()).ToArray();
                kernel.Bind(types).To(calcType).InSingletonScope();
            }

            // collect all renderers types
            Type[] rendererTypes = pluginTypes
                                   .SelectMany(p => GetRenderers(p))
                                   .ToArray();

            foreach (Type rendererType in rendererTypes)
            {
                var types = new[] { rendererType }.Concat(rendererType.GetInterfaces()).ToArray();
                kernel.Bind(rendererType).ToSelf().InSingletonScope();
            }

            // collect all event provider implementations
            Type[] eventProviderTypes = pluginTypes
                                        .SelectMany(p => GetAstroEventProviders(p))
                                        .ToArray();

            foreach (Type eventProviderType in eventProviderTypes)
            {
                kernel.Bind(eventProviderType).ToSelf().InSingletonScope();
            }

            foreach (Type pluginType in pluginTypes)
            {
                progress.Report($"Creating plugin {pluginType}");

                kernel.Bind(pluginType).ToSelf().InSingletonScope();
                var plugin = kernel.Get(pluginType) as AbstractPlugin;

                // add settings configurations
                uiIntegration.SettingItems.AddRange(plugin.SettingItems);

                // add configured toolbar buttons
                uiIntegration.ToolbarButtons.AddRange(plugin.ToolbarItems);

                // add menu items
                uiIntegration.MenuItems.AddRange(plugin.MenuItems);

                plugins.Add(plugin);
            }

            // Default rendering order for BaseRenderer descendants.
            uiIntegration.SettingItems.Add("Rendering", new SettingItem("RenderingOrder", new RenderingOrder(), typeof(RenderersListSettingControl)));

            var settings = kernel.Get <ISettings>();

            // set settings defaults
            foreach (string group in uiIntegration.SettingItems.Groups)
            {
                foreach (var item in uiIntegration.SettingItems[group])
                {
                    settings.Set(item.Name, item.DefaultValue);
                }
            }

            settings.Save("Defaults");

            progress.Report($"Loading settings");

            settings.Load();

            SetLanguage(settings.Get <string>("Language"));
            SetColorSchema(settings.Get <ColorSchema>("Schema"));

            SkyContext context = new SkyContext(
                new Date(DateTime.Now).ToJulianEphemerisDay(),
                new CrdsGeographical(settings.Get <CrdsGeographical>("ObserverLocation")));

            progress.Report($"Creating calculators");

            var calculators = calcTypes
                              .Select(c => kernel.Get(c))
                              .Cast <BaseCalc>()
                              .ToArray();

            progress.Report($"Creating event providers");

            var eventProviders = eventProviderTypes
                                 .Select(c => kernel.Get(c))
                                 .Cast <BaseAstroEventsProvider>()
                                 .ToArray();

            progress.Report($"Creating renderers");

            var renderers = rendererTypes.Select(r => kernel.Get(r)).Cast <BaseRenderer>().ToArray();

            kernel.Get <Sky>().Initialize(context, calculators, eventProviders);

            kernel.Get <SkyMap>().Initialize(context, renderers);

            Debug.Write("Application container has been configured.");

            progress.Report($"Initializing shell");

            settings.SettingValueChanged += (settingName, value) =>
            {
                if (settingName == "Schema")
                {
                    SetColorSchema((ColorSchema)value);
                }
                else if (settingName == "Language")
                {
                    SetLanguage((string)value);
                }
            };

            foreach (var plugin in plugins)
            {
                plugin.Initialize();
            }
        }
Пример #2
0
        private void ConfigureContainer(IProgress <string> progress)
        {
            kernel.Bind <ICommandLineArgs>().ToConstant(commandLineArgs).InSingletonScope();
            kernel.Bind <ISettings, Settings>().To <Settings>().InSingletonScope();
            kernel.Bind <ISky, Sky>().To <Sky>().InSingletonScope();
            kernel.Bind <ISkyMap, SkyMap>().To <SkyMap>().InSingletonScope();
            kernel.Bind <IGeoLocationsManager, GeoLocationsManager>().To <GeoLocationsManager>().InSingletonScope();
            kernel.Bind <IMainWindow, MainVM>().To <MainVM>().InSingletonScope();
            kernel.Bind <UIElementsIntegration>().ToSelf().InSingletonScope();
            UIElementsIntegration uiIntegration = kernel.Get <UIElementsIntegration>();

            ICollection <AbstractPlugin> plugins = new List <AbstractPlugin>();

            string homeFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            IEnumerable <string> pluginPaths = Directory.EnumerateFiles(homeFolder, "Astrarium.Plugins.*.dll", SearchOption.AllDirectories);

            progress.Report("Loading plugins");

            foreach (string path in pluginPaths)
            {
                try
                {
                    var plugin = Assembly.UnsafeLoadFrom(path);

                    // get singletons defined in plugin
                    var singletons = plugin.GetExportedTypes().Where(t => t.IsDefined(typeof(SingletonAttribute), false)).ToArray();
                    foreach (var singletonImpl in singletons)
                    {
                        var singletonAttr = singletonImpl.GetCustomAttribute <SingletonAttribute>();
                        if (singletonAttr.InterfaceType != null)
                        {
                            if (!singletonAttr.InterfaceType.IsAssignableFrom(singletonImpl))
                            {
                                throw new Exception($"Interface type {singletonAttr.InterfaceType} is not assignable from {singletonImpl}");
                            }
                            kernel.Bind(singletonAttr.InterfaceType).To(singletonImpl).InSingletonScope();
                        }
                        else
                        {
                            kernel.Bind(singletonImpl).ToSelf().InSingletonScope();
                        }
                    }

                    Log.Info($"Loaded plugin {plugin.FullName}");
                }
                catch (Exception ex)
                {
                    Log.Error($"Unable to load plugin assembly with path {path}. {ex})");
                }
            }

            // collect all plugins implementations
            Type[] pluginTypes = AppDomain.CurrentDomain.GetAssemblies()
                                 .SelectMany(a => a.GetTypes())
                                 .Where(t => typeof(AbstractPlugin).IsAssignableFrom(t) && !t.IsAbstract)
                                 .ToArray();

            // collect all calculators types
            Type[] calcTypes = pluginTypes
                               .SelectMany(p => GetCalculators(p))
                               .ToArray();

            foreach (Type calcType in calcTypes)
            {
                var types = new[] { calcType }.Concat(calcType.GetInterfaces()).ToArray();
                kernel.Bind(types).To(calcType).InSingletonScope();
            }

            // collect all renderers types
            Type[] rendererTypes = pluginTypes
                                   .SelectMany(p => GetRenderers(p))
                                   .ToArray();

            foreach (Type rendererType in rendererTypes)
            {
                var types = new[] { rendererType }.Concat(rendererType.GetInterfaces()).ToArray();
                kernel.Bind(types).To(rendererType).InSingletonScope();
            }

            // collect all event provider implementations
            Type[] eventProviderTypes = pluginTypes
                                        .SelectMany(p => GetAstroEventProviders(p))
                                        .ToArray();

            foreach (Type eventProviderType in eventProviderTypes)
            {
                var types = new[] { eventProviderType }.Concat(eventProviderType.GetInterfaces()).ToArray();
                kernel.Bind(types).To(eventProviderType).InSingletonScope();
            }

            foreach (Type pluginType in pluginTypes)
            {
                progress.Report($"Creating plugin {pluginType}");

                try
                {
                    // plugin is a singleton
                    kernel.Bind(pluginType).ToSelf().InSingletonScope();
                    var plugin = kernel.Get(pluginType) as AbstractPlugin;

                    // add settings definitions
                    uiIntegration.SettingDefinitions.AddRange(plugin.SettingDefinitions);

                    // add settings sections
                    uiIntegration.SettingSections.AddRange(plugin.SettingSections);

                    // add configured toolbar buttons
                    uiIntegration.ToolbarButtons.AddRange(plugin.ToolbarItems);

                    // add menu items
                    uiIntegration.MenuItems.AddRange(plugin.MenuItems);

                    plugins.Add(plugin);
                }
                catch (Exception ex)
                {
                    Log.Error($"Unable to create plugin of type {pluginType.Name}: {ex}");
                    kernel.Unbind(pluginType);
                }
            }

            progress.Report($"Creating renderers");

            var renderers             = rendererTypes.Select(r => kernel.Get(r)).Cast <BaseRenderer>().ToArray();
            var defaultRenderingOrder = new RenderingOrder(renderers.OrderBy(r => r.Order).Select(r => new RenderingOrderItem(r)));

            uiIntegration.SettingDefinitions.Add(new SettingDefinition("RenderingOrder", defaultRenderingOrder, false));

            var settings = kernel.Get <ISettings>();

            settings.Define(uiIntegration.SettingDefinitions);
            settings.Save("Defaults");

            progress.Report($"Loading settings");

            settings.Load();

            SetLanguage(settings.Get <string>("Language"));
            SetColorSchema(settings.Get <ColorSchema>("Schema"), settings.Get("AppTheme", "DeepBlue"));

            SkyContext context = new SkyContext(
                new Date(DateTime.Now).ToJulianEphemerisDay(),
                new CrdsGeographical(settings.Get <CrdsGeographical>("ObserverLocation")));

            progress.Report($"Creating calculators");

            var calculators = calcTypes
                              .Select(c => kernel.Get(c))
                              .Cast <BaseCalc>()
                              .ToArray();

            progress.Report($"Creating event providers");

            var eventProviders = eventProviderTypes
                                 .Select(c => kernel.Get(c))
                                 .Cast <BaseAstroEventsProvider>()
                                 .ToArray();

            progress.Report($"Initializing sky");
            kernel.Get <Sky>().Initialize(context, calculators, eventProviders);

            progress.Report($"Initializing sky map");
            kernel.Get <SkyMap>().Initialize(context, renderers);

            Log.Debug("Application container has been configured.");

            progress.Report($"Initializing shell");

            settings.SettingValueChanged += (settingName, value) =>
            {
                if (settingName == "Schema" || settingName == "AppTheme")
                {
                    SetColorSchema(settings.Get("Schema", ColorSchema.Night), settings.Get("AppTheme", "DeepBlue"));
                }
                else if (settingName == "Language")
                {
                    SetLanguage((string)value);
                }
            };

            foreach (var plugin in plugins)
            {
                plugin.Initialize();
            }
        }