예제 #1
0
        public static void MystiqueSetup(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddOptions();
            services.Configure <ConnectionStringSetting>(configuration.GetSection("ConnectionStringSetting"));

            services.AddSingleton <IMvcModuleSetup, MvcModuleSetup>();
            services.AddScoped <IPluginManager, PluginManager>();
            services.AddScoped <IUnitOfWork, UnitOfWork>();
            services.AddSingleton <IActionDescriptorChangeProvider>(MystiqueActionDescriptorChangeProvider.Instance);
            services.AddSingleton(MystiqueActionDescriptorChangeProvider.Instance);

            var mvcBuilder = services.AddMvc().AddRazorRuntimeCompilation(o =>
            {
                foreach (var item in _presets)
                {
                    o.AdditionalReferencePaths.Add(item);
                }

                AdditionalReferencePathHolder.AdditionalReferencePaths = o.AdditionalReferencePaths;
            });

            var provider = services.BuildServiceProvider();

            using (var scope = provider.CreateScope())
            {
                var option = scope.ServiceProvider.GetService <MvcRazorRuntimeCompilationOptions>();

                var unitOfWork        = scope.ServiceProvider.GetService <IUnitOfWork>();
                var allEnabledPlugins = unitOfWork.PluginRepository.GetAllEnabledPlugins();

                foreach (var plugin in allEnabledPlugins)
                {
                    var context             = new CollectibleAssemblyLoadContext();
                    var moduleName          = plugin.Name;
                    var filePath            = $"{AppDomain.CurrentDomain.BaseDirectory}Modules\\{moduleName}\\{moduleName}.dll";
                    var referenceFolderPath = $"{AppDomain.CurrentDomain.BaseDirectory}Modules\\{moduleName}";

                    _presets.Add(filePath);
                    using (var fs = new FileStream(filePath, FileMode.Open))
                    {
                        var assembly = context.LoadFromStream(fs);

                        DefaultReferenceLoader loader = new DefaultReferenceLoader(referenceFolderPath, $"{moduleName}.dll");
                        loader.LoadStreamsIntoContext(context);

                        var controllerAssemblyPart = new MystiqueAssemblyPart(assembly);
                        mvcBuilder.PartManager.ApplicationParts.Add(controllerAssemblyPart);
                        PluginsLoadContexts.AddPluginContext(plugin.Name, context);
                    }
                }
            }

            services.Configure <RazorViewEngineOptions>(o =>
            {
                o.AreaViewLocationFormats.Add("/Modules/{2}/Views/{1}/{0}" + RazorViewEngine.ViewExtension);
                o.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
            });
        }
예제 #2
0
        public static void MystiqueSetup(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddOptions();
            services.Configure <ConnectionStringSetting>(configuration.GetSection("ConnectionStringSetting"));

            services.AddSingleton <IMvcModuleSetup, MvcModuleSetup>();
            services.AddScoped <IPluginManager, PluginManager>();
            services.AddScoped <IUnitOfWork, UnitOfWork>();
            services.AddSingleton <INotificationRegister, NotificationRegister>();
            services.AddSingleton <IActionDescriptorChangeProvider>(MystiqueActionDescriptorChangeProvider.Instance);
            services.AddSingleton <IReferenceContainer, DefaultReferenceContainer>();
            services.AddSingleton <IReferenceLoader, DefaultReferenceLoader>();
            services.AddSingleton(MystiqueActionDescriptorChangeProvider.Instance);

            IMvcBuilder mvcBuilder = services.AddMvc();

            ServiceProvider provider = services.BuildServiceProvider();

            using (IServiceScope scope = provider.CreateScope())
            {
                MvcRazorRuntimeCompilationOptions option = scope.ServiceProvider.GetService <MvcRazorRuntimeCompilationOptions>();

                IUnitOfWork unitOfWork = scope.ServiceProvider.GetService <IUnitOfWork>();
                List <ViewModels.PluginListItemViewModel> allEnabledPlugins = unitOfWork.PluginRepository.GetAllEnabledPlugins();
                IReferenceLoader loader = scope.ServiceProvider.GetService <IReferenceLoader>();

                foreach (ViewModels.PluginListItemViewModel plugin in allEnabledPlugins)
                {
                    CollectibleAssemblyLoadContext context = new CollectibleAssemblyLoadContext(plugin.Name);
                    string moduleName          = plugin.Name;
                    string filePath            = $"{AppDomain.CurrentDomain.BaseDirectory}Modules/{moduleName}/{moduleName}.dll";
                    string referenceFolderPath = $"{AppDomain.CurrentDomain.BaseDirectory}Modules/{moduleName}";

                    _presets.Add(filePath);
                    using (FileStream fs = new FileStream(filePath, FileMode.Open))
                    {
                        System.Reflection.Assembly assembly = context.LoadFromStream(fs);
                        context.SetEntryPoint(assembly);
                        loader.LoadStreamsIntoContext(context, referenceFolderPath, assembly);

                        MystiqueAssemblyPart controllerAssemblyPart = new MystiqueAssemblyPart(assembly);
                        mvcBuilder.PartManager.ApplicationParts.Add(controllerAssemblyPart);
                        PluginsLoadContexts.Add(plugin.Name, context);

                        var providers = assembly.GetExportedTypes().Where(p => p.GetInterfaces().Any(x => x.Name == "INotificationProvider"));

                        if (providers.Any())
                        {
                            var register = scope.ServiceProvider.GetService <INotificationRegister>();

                            foreach (var p in providers)
                            {
                                var obj    = (INotificationProvider)assembly.CreateInstance(p.FullName);
                                var result = obj.GetNotifications();

                                foreach (var item in result)
                                {
                                    foreach (var i in item.Value)
                                    {
                                        register.Subscribe(item.Key, i);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            mvcBuilder.AddRazorRuntimeCompilation(o =>
            {
                foreach (string item in _presets)
                {
                    o.AdditionalReferencePaths.Add(item);
                }

                AdditionalReferencePathHolder.AdditionalReferencePaths = o.AdditionalReferencePaths;
            });

            services.Configure <RazorViewEngineOptions>(o =>
            {
                o.AreaViewLocationFormats.Add("/Modules/{2}/Views/{1}/{0}" + RazorViewEngine.ViewExtension);
                o.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
            });
        }
예제 #3
0
        public static void MystiqueSetup(this IServiceCollection services, IConfiguration configuration)
        {
            _serviceCollection = services;

            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();
            services.AddSingleton <IMvcModuleSetup, MvcModuleSetup>();
            services.AddScoped <IPluginManager, PluginManager>();
            services.AddScoped <ISystemManager, SystemManager>();
            services.AddScoped <IUnitOfWork, Repository.MySql.UnitOfWork>();
            services.AddSingleton <INotificationRegister, NotificationRegister>();
            services.AddSingleton <IActionDescriptorChangeProvider>(MystiqueActionDescriptorChangeProvider.Instance);
            services.AddSingleton <IReferenceContainer, DefaultReferenceContainer>();
            services.AddSingleton <IReferenceLoader, DefaultReferenceLoader>();
            services.AddSingleton(MystiqueActionDescriptorChangeProvider.Instance);

            IMvcBuilder mvcBuilder = services.AddMvc();

            ServiceProvider provider = services.BuildServiceProvider();

            using (IServiceScope scope = provider.CreateScope())
            {
                IUnitOfWork unitOfWork = scope.ServiceProvider.GetService <IUnitOfWork>();

                if (unitOfWork.CheckDatabase())
                {
                    List <ViewModels.PluginListItemViewModel> allEnabledPlugins = unitOfWork.PluginRepository.GetAllEnabledPlugins();
                    IReferenceLoader loader = scope.ServiceProvider.GetService <IReferenceLoader>();

                    foreach (ViewModels.PluginListItemViewModel plugin in allEnabledPlugins)
                    {
                        CollectibleAssemblyLoadContext context = new CollectibleAssemblyLoadContext(plugin.Name);
                        string moduleName = plugin.Name;

                        string filePath            = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Modules", moduleName, $"{moduleName}.dll");
                        string viewFilePath        = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Modules", moduleName, $"{moduleName}.Views.dll");
                        string referenceFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Modules", moduleName);

                        _presets.Add(filePath);
                        using (FileStream fs = new FileStream(filePath, FileMode.Open))
                        {
                            Assembly assembly = context.LoadFromStream(fs);
                            context.SetEntryPoint(assembly);

                            loader.LoadStreamsIntoContext(context, referenceFolderPath, assembly);

                            MystiqueAssemblyPart controllerAssemblyPart = new MystiqueAssemblyPart(assembly);
                            mvcBuilder.PartManager.ApplicationParts.Add(controllerAssemblyPart);
                            PluginsLoadContexts.Add(plugin.Name, context);

                            BuildNotificationProvider(assembly, scope);
                        }

                        using (FileStream fsView = new FileStream(viewFilePath, FileMode.Open))
                        {
                            Assembly viewAssembly = context.LoadFromStream(fsView);
                            loader.LoadStreamsIntoContext(context, referenceFolderPath, viewAssembly);

                            MystiqueRazorAssemblyPart moduleView = new MystiqueRazorAssemblyPart(viewAssembly, moduleName);
                            mvcBuilder.PartManager.ApplicationParts.Add(moduleView);
                        }

                        context.Enable();
                    }
                }
            }

            AssemblyLoadContextResoving();

            services.Configure <RazorViewEngineOptions>(o =>
            {
                o.AreaViewLocationFormats.Add("/Modules/{2}/Views/{1}/{0}" + RazorViewEngine.ViewExtension);
                o.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
            });

            services.Replace <IViewCompilerProvider, MystiqueViewCompilerProvider>();
        }
예제 #4
0
        public static void MystiqueSetup(this IServiceCollection services)
        {
            services.AddOptions();
            services.AddSingleton <IMvcPluginSetup, MvcPluginSetup>();
            services.AddSingleton <IReferenceContainer, DefaultReferenceContainer>();
            services.AddSingleton <IReferenceLoader, DefaultReferenceLoader>();
            services.AddSingleton <IActionDescriptorChangeProvider>(MystiqueActionDescriptorChangeProvider.Instance);
            services.AddSingleton(MystiqueActionDescriptorChangeProvider.Instance);
            services.AddScoped <PluginPackage>();
            services.AddScoped <IPluginManager, PluginManager>();

            var mvcBuilder = services.AddMvc();

            var pluginFolder  = Path.Combine(Environment.CurrentDirectory, "host_plugins");
            var plugins_cache = Path.Combine(pluginFolder, "plugins_cache.json");

            if (File.Exists(plugins_cache))
            {
                using var scope = services.BuildServiceProvider().CreateScope();
                var refsLoader    = scope.ServiceProvider.GetService <IReferenceLoader>();
                var loggerFactory = scope.ServiceProvider.GetService <ILoggerFactory>();
                var plugins       = JsonConvert.DeserializeObject <PluginModel[]>(File.ReadAllText(plugins_cache, System.Text.Encoding.UTF8));
                foreach (var plugin in plugins)
                {
                    var filePath = Path.Combine(pluginFolder, plugin.Name, $"{plugin.Name}.dll");
                    if (!File.Exists(filePath))
                    {
                        continue;
                    }

                    try
                    {
                        var referenceFolderPath = Path.GetDirectoryName(filePath);
                        using (var fs = new FileStream(filePath, FileMode.Open))
                        {
                            var context  = plugin.PluginContext = new CollectibleAssemblyLoadContext();
                            var assembly = context.LoadFromStream(fs);
                            refsLoader.LoadStreamsIntoContext(context, referenceFolderPath, assembly);

                            var controllerAssemblyPart = new MystiqueAssemblyPart(assembly);
                            mvcBuilder.PartManager.ApplicationParts.Add(controllerAssemblyPart);
                            PluginsLoadContexts.UpsertPluginContext(plugin);
                        }
                        presets.Add(filePath);
                    }
                    catch (Exception ex)
                    {
                        loggerFactory.CreateLogger <CollectibleAssemblyLoadContext>().LogWarning(new EventId(450), $"加载插件失败 '{plugin}'", ex);
                    }
                }
            }

            mvcBuilder.AddRazorRuntimeCompilation(o =>
            {
                foreach (var item in presets)
                {
                    o.AdditionalReferencePaths.Add(item);
                }

                AdditionalReferencePathHolder.AdditionalReferencePaths = o.AdditionalReferencePaths;
            });

            services.Configure <RazorViewEngineOptions>(o =>
            {
                o.AreaViewLocationFormats.Add("/Modules/{2}/Views/{1}/{0}" + RazorViewEngine.ViewExtension);
                o.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
            });
        }