Example #1
0
        private void LoadPrivateBinAssemblies(MvcRazorRuntimeCompilationOptions opt)
        {
            var binPath = Path.Combine(WebRoot, "privatebin");

            if (Directory.Exists(binPath))
            {
                var files = Directory.GetFiles(binPath);
                foreach (var file in files)
                {
                    if (!file.EndsWith(".dll", StringComparison.CurrentCultureIgnoreCase) &&
                        !file.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }

                    try
                    {
                        var asm = AssemblyLoadContext.Default.LoadFromAssemblyPath(file);
                        opt.AdditionalReferencePaths.Add(file);

                        LoadedPrivateAssemblies.Add(file);
                    }
                    catch (Exception ex)
                    {
                        FailedPrivateAssemblies.Add(file + "\n    - " + ex.Message);
                    }
                }
            }
        }
 public RazorReferenceManager(
     ApplicationPartManager partManager,
     IOptions <MvcRazorRuntimeCompilationOptions> options)
 {
     _partManager = partManager;
     _options     = options.Value;
 }
Example #3
0
    public RuntimeCompilationFileProvider(IOptions <MvcRazorRuntimeCompilationOptions> options)
    {
        if (options == null)
        {
            throw new ArgumentNullException(nameof(options));
        }

        _options = options.Value;
    }
Example #4
0
 static void ConfigureRuntimeCompilationOptions(MvcRazorRuntimeCompilationOptions options)
 {
     // Workaround for incorrectly generated deps file. The build output has all of the binaries required to compile. We'll grab these and
     // add it to the list of assemblies runtime compilation uses.
     foreach (var path in Directory.EnumerateFiles(AppContext.BaseDirectory, "*.dll"))
     {
         options.AdditionalReferencePaths.Add(path);
     }
 }
Example #5
0
        public void Configure(MvcRazorRuntimeCompilationOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            options.FileProviders.Add(_resourceFileProviderFactory.Create());
        }
Example #6
0
        private static IFileProvider GetCompositeFileProvider(MvcRazorRuntimeCompilationOptions options)
        {
            var fileProviders = options.FileProviders;

            if (fileProviders.Count == 1)
            {
                return(fileProviders[0]);
            }

            return(new CompositeFileProvider(fileProviders));
        }
Example #7
0
 public FileBlogRepository(IWebHostEnvironment env,
                           IOptions <MvcRazorRuntimeCompilationOptions> optionsAccessor,
                           IMemoryCache memoryCache,
                           ILoggerFactory loggerFactory,
                           IPostRepository postRepository) : base(env, memoryCache)
 {
     Logger          = loggerFactory.CreateLogger <FileBlogRepository>();
     _postRepository = postRepository;
     _filesFolder    = "{0}/posts/{1}/files/";
     _fileUrl        = "/posts/{0}/files/{1}";
     _blogsFile      = env.WebRootPath + @"\blogs.json";
     _themesFolder   = env.WebRootPath + @"\themes\";
     _razorRuntimeCompilationOptions = optionsAccessor.Value;
 }
        private static IFileProvider GetCompositeFileProvider(MvcRazorRuntimeCompilationOptions options)
        {
            var fileProviders = options.FileProviders;

            if (fileProviders.Count == 0)
            {
                var message = $"'{typeof(MvcRazorRuntimeCompilationOptions).FullName}.{nameof(MvcRazorRuntimeCompilationOptions.FileProviders)}' must not be empty. At least one '{typeof(IFileProvider).FullName}' is required to locate a view for rendering.";
                throw new InvalidOperationException(message);
            }
            else if (fileProviders.Count == 1)
            {
                return(fileProviders[0]);
            }

            return(new CompositeFileProvider(fileProviders));
        }
Example #9
0
    private static IFileProvider GetCompositeFileProvider(MvcRazorRuntimeCompilationOptions options)
    {
        var fileProviders = options.FileProviders;

        if (fileProviders.Count == 0)
        {
            var message = Resources.FormatFileProvidersAreRequired(
                typeof(MvcRazorRuntimeCompilationOptions).FullName,
                nameof(MvcRazorRuntimeCompilationOptions.FileProviders),
                typeof(IFileProvider).FullName);
            throw new InvalidOperationException(message);
        }
        else if (fileProviders.Count == 1)
        {
            return(fileProviders[0]);
        }

        return(new CompositeFileProvider(fileProviders));
    }
    public void GetCompilationReferences_CombinesApplicationPartAndOptionMetadataReferences()
    {
        // Arrange
        var options = new MvcRazorRuntimeCompilationOptions();
        var additionalReferencePath = "additional-path";

        options.AdditionalReferencePaths.Add(additionalReferencePath);

        var applicationPartManager = GetApplicationPartManager();
        var referenceManager       = new RazorReferenceManager(
            applicationPartManager,
            Options.Create(options));

        var expected = new[] { ApplicationPartReferencePath, additionalReferencePath };

        // Act
        var references = referenceManager.GetReferencePaths();

        // Assert
        Assert.Equal(expected, references);
    }
Example #11
0
        public static IApplicationBuilder UsePlugin(this IApplicationBuilder applicationBuilder)
        {
            var           serviceProvider = applicationBuilder.ApplicationServices;
            PluginOptions _pluginOptions  = serviceProvider.GetService <IOptions <PluginOptions> >().Value;

            if (!_pluginOptions.Enable)
            {
                return(applicationBuilder);
            }
            MvcRazorRuntimeCompilationOptions option = serviceProvider.GetService <IOptions <MvcRazorRuntimeCompilationOptions> >()?.Value;

            var pluginsLoadContexts = serviceProvider.GetService <IPluginsAssemblyLoadContexts>();
            //AssemblyLoadContextResoving(pluginsLoadContexts);
            IReferenceLoader loader                 = serviceProvider.GetService <IReferenceLoader>();
            var moduleSetup                         = serviceProvider.GetService <IMvcModuleSetup>();
            IPluginManagerService pluginManager     = serviceProvider.GetService <IPluginManagerService>();
            List <PluginInfoDto>  allEnabledPlugins = pluginManager.GetAllPlugins().ConfigureAwait(false).GetAwaiter().GetResult();

            ModuleChangeDelegate moduleStarted = (moduleEvent, context) =>
            {
                if (context?.PluginContext == null || context?.PluginContext.PluginEntityAssemblies.Count() == 0)
                {
                    return;
                }

                //var pluginContexts = pluginsLoadContexts.All().Select(c => c.PluginContext).SkipWhile(c => c == null);
                switch (moduleEvent)
                {
                case ModuleEvent.Installed:
                    HandleModuleInstallEvent(serviceProvider, context);
                    break;

                case ModuleEvent.Loaded:
                    HandleModuleLoadEvent(serviceProvider, context);
                    break;

                case ModuleEvent.Started:
                    break;

                case ModuleEvent.Stoped:
                    break;

                case ModuleEvent.UnInstalled:
                    HandleModuleUnintallEvent(serviceProvider, context);
                    break;

                default:
                    break;
                }
            };

            moduleSetup.ModuleChangeEventHandler += moduleStarted;
            var env = serviceProvider.GetService <IHostEnvironment>();

            foreach (var plugin in allEnabledPlugins)
            {
                string filePath = Path.Combine(env.ContentRootPath, _pluginOptions.InstallBasePath, plugin.Name, $"{ plugin.Name}.dll");
                //option.FileProviders.Add(new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, _pluginOptions.InstallBasePath, plugin.Name)));
                option.AdditionalReferencePaths.Add(filePath);
                if (plugin.IsEnable)
                {
                    moduleSetup.EnableModule(plugin.Name);
                }
                else
                {
                    moduleSetup.LoadModule(plugin.Name, false);
                }
            }

            AdditionalReferencePathHolder.AdditionalReferencePaths = option?.AdditionalReferencePaths;
            var razorViewEngineOptions = serviceProvider.GetService <IOptions <RazorViewEngineOptions> >()?.Value;

            razorViewEngineOptions?.AreaViewLocationFormats.Add("/Plugins/{2}/Views/{1}/{0}" + RazorViewEngine.ViewExtension);
            razorViewEngineOptions?.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");


            return(applicationBuilder);
        }
Example #12
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");
            });
        }
        public static void MystiqueSetup(this IServiceCollection services, IConfiguration configuration)
        {
            _serviceCollection = services;

            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())
            {
                MvcRazorRuntimeCompilationOptions option = scope.ServiceProvider.GetService <MvcRazorRuntimeCompilationOptions>();

                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 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);
                        }

                        context.Enable();
                    }
                }
            }

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

                AdditionalReferencePathHolder.AdditionalReferencePaths = o.AdditionalReferencePaths;
            });

            AssemblyLoadContextResoving();

            services.Configure <RazorViewEngineOptions>(o =>
            {
                o.AreaViewLocationFormats.Add("/Modules/{2}/Views/{1}/{0}" + RazorViewEngine.ViewExtension);
                o.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
            });
        }
Example #14
0
        // Adds Runtime Compilation support
        public static IServiceCollection AddMultiTenantRuntimeCompilation(this IServiceCollection services, IWebHostEnvironment environment)
        {
            services.TryAddEnumerable(ServiceDescriptor.Transient <IConfigureOptions <MvcRazorRuntimeCompilationOptions>, PublicMvcRazorRuntimeCompilationOptionsSetup>());

            services.AddSingleton <PublicActionEndpointFactory>();
            services.AddSingleton <PageLoader, RuntimeRazorPageLoader>();

            // services.AddTransient<IRazorPageFactoryProvider, MultiTenantRuntimePageFactoryProvider>();
            services.AddSingleton <IViewCompilerProvider, RuntimeMultiViewCompilerProvider>();
            services.AddSingleton <IRazorViewEngine, RazorMultiViewEngine>();
            services.AddSingleton <PublicRazorReferenceManager>();
            services.AddSingleton <PublicCSharpCompiler>();

            services.AddSingleton <IDictionary <string, RazorProjectEngine> >(s => {
                var csharpCompiler   = s.GetRequiredService <PublicCSharpCompiler>();
                var referenceManager = s.GetRequiredService <PublicRazorReferenceManager>();
                var dictionary       = new Dictionary <string, RazorProjectEngine>();

                var options        = s.GetService <IOptions <RazorMultiViewEngineOptions> >()?.Value;
                var compileOptions = s.GetService <IOptions <MvcRazorRuntimeCompilationOptions> >();

                if (options is null)
                {
                    // Log a warning that there are no options and dont add any engines.
                    return(dictionary);
                }

                if (!string.IsNullOrEmpty(options.DefaultViewLibrary.PathRelativeToContentRoot))
                {
                    var path       = Path.GetFullPath(Path.Combine(environment.ContentRootPath, options.DefaultViewLibrary.PathRelativeToContentRoot));
                    var liboptions = new MvcRazorRuntimeCompilationOptions();
                    liboptions.FileProviders.Add(new PhysicalFileProvider(path));
                    var engine = GetEngine(csharpCompiler, referenceManager,
                                           new PublicFileProviderRazorProjectFileSystem(
                                               new PublicRuntimeCompilationFileProvider(Options.Create(liboptions))),
                                           options.DefaultViewLibrary.AssemblyName);
                    dictionary.Add($"{options.DefaultViewLibrary.AssemblyName}.Views", engine);
                }

                // Assumes they are all Loaded at this point
                // and that the paths have been checked and are valid
                foreach (var viewLibrary in options.ViewLibraries)
                {
                    if (dictionary.ContainsKey(viewLibrary.AssemblyName))
                    {
                        // TODO: Invalid config should have been picked up here
                        continue;
                    }

                    if (!string.IsNullOrEmpty(viewLibrary.PathRelativeToContentRoot))
                    {
                        var path       = Path.GetFullPath(Path.Combine(environment.ContentRootPath, viewLibrary.PathRelativeToContentRoot));
                        var liboptions = new MvcRazorRuntimeCompilationOptions();
                        liboptions.FileProviders.Add(new PhysicalFileProvider(path));
                        var engine = GetEngine(csharpCompiler, referenceManager,
                                               new PublicFileProviderRazorProjectFileSystem(
                                                   new PublicRuntimeCompilationFileProvider(Options.Create(liboptions))), viewLibrary.AssemblyName);


                        dictionary.Add($"{viewLibrary.AssemblyName}.Views", engine);
                    }
                }
                return(dictionary);
            });

            return(services);
        }