Ejemplo n.º 1
0
        public Assembly LoadPlugin(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentException($"'{nameof(path)}' cannot be null or empty.", nameof(path));
            }

            string v = Path.GetFullPath(Path.Combine(
                                            Path.GetDirectoryName(
                                                Path.GetDirectoryName(
                                                    Path.GetDirectoryName(
                                                        Path.GetDirectoryName(
                                                            Path.GetDirectoryName(typeof(Program).Assembly.Location)))))));
            var    root           = v;
            string v1             = Path.GetFullPath(Path.Combine(root, path.Replace('\\', Path.DirectorySeparatorChar)));
            string pluginLocation = v1;

            _logger.LogInfo($"Loading plugin from: {pluginLocation}");

            PluginLoadContext loadContext = new PluginLoadContext(pluginLocation);

            loadContext.GetType();
            Assembly assembly = loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation)));
            var      loaded   = assembly;

            return(loaded);
        }
        /// <summary>
        /// Helper method to load an assembly which contains a single plugin
        /// </summary>
        /// <param name="pluginLocation">string</param>
        /// <returns>IPlugin</returns>
        private static IPlugin LoadPlugin(string pluginLocation)
        {
            if (!File.Exists(pluginLocation))
            {
                Console.WriteLine($"Can't find: {pluginLocation}");
                return(null);
            }
            Console.WriteLine($"Loading plugin from: {pluginLocation}");

            var loadContext = new PluginLoadContext(pluginLocation);
            var assembly    = loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation)));

            var interfaceType = typeof(IPlugin);

            foreach (var type in assembly.GetExportedTypes())
            {
                if (!type.GetInterfaces().Contains(interfaceType))
                {
                    continue;
                }
                var plugin = Activator.CreateInstance(type) as IPlugin;
                return(plugin);
            }
            return(null);
        }
Ejemplo n.º 3
0
        private Type?LoadType()
        {
            if (TypeName == null)
            {
                throw new ArgumentNullException(nameof(TypeName), "The type name must be specified");
            }
            if (AssemblyName == null)
            {
                throw new ArgumentNullException(nameof(TypeName), "The assembly name must be specified");
            }

            if (string.IsNullOrWhiteSpace(AssemblyPath))
            {
                var assemblies = AppDomain.CurrentDomain.GetAssemblies();
                var assembly   = assemblies.First(x => x.GetName().Name == AssemblyName);
                var type       = assembly.GetType(TypeName);
                return(type);
            }
            else
            {
                var loadContext = new PluginLoadContext(AssemblyPath);
                var assembly    = loadContext.LoadFromAssemblyName(new AssemblyName(AssemblyName));
                var type        = assembly.GetType(TypeName);
                return(type);
            }
        }
        /// <summary>
        /// Helper method to load an assembly which contains plugins
        /// </summary>
        /// <param name="pluginBuilder">IPluginBuilder</param>
        /// <param name="pluginAssemblyLocation">string</param>
        /// <returns>IPlugin</returns>
        private static Assembly LoadPlugin(IPluginBuilder pluginBuilder, string pluginAssemblyLocation)
        {
            if (!File.Exists(pluginAssemblyLocation))
            {
                // TODO: Log an error, how to get a logger here?
                return(null);
            }

            // This allows validation like AuthenticodeExaminer
            if (!pluginBuilder.ValidatePlugin(pluginAssemblyLocation))
            {
                return(null);
            }

            // TODO: Log verbose that we are loading a plugin
            var pluginName = Path.GetFileNameWithoutExtension(pluginAssemblyLocation);
            // TODO: Decide if we rather have this to come up with the name: AssemblyName.GetAssemblyName(pluginLocation)
            var pluginAssemblyName = new AssemblyName(pluginName);

            if (AssemblyLoadContext.Default.TryGetAssembly(pluginAssemblyName, out _))
            {
                return(null);
            }
            var loadContext = new PluginLoadContext(pluginAssemblyLocation, pluginName);

            return(loadContext.LoadFromAssemblyName(pluginAssemblyName));
        }
Ejemplo n.º 5
0
        private Assembly LoadPluginAssembly(string path)
        {
            string pluginLocation = path.Replace('\\', Path.DirectorySeparatorChar);

            _logger.LogDebug($"Loading assembly file: {pluginLocation}");
            PluginLoadContext loadContext = new PluginLoadContext(pluginLocation);

            return(loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation))));
        }
Ejemplo n.º 6
0
        internal static Assembly LoadPlugin(string relativePath)
        {
            var    root           = GetRoot();
            string pluginLocation = Path.GetFullPath(Path.Combine(root, relativePath.Replace('\\', Path.DirectorySeparatorChar)));

            Debug.Log($"Loading commands from: {pluginLocation}");
            PluginLoadContext loadContext = new PluginLoadContext(pluginLocation);

            return(loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation))));
        }
Ejemplo n.º 7
0
        public static IMvcBuilder AddPluginFutures(this IMvcBuilder mvcBuilder, IHostEnvironment environment)
        {
            var pluginContext = new PluginContext();

            var pluginsFolder = Path.Combine(environment.ContentRootPath, pluginFolderName);
            foreach (var dir in Directory.GetDirectories(pluginsFolder))
            {
                var pluginFolder = Path.GetFileName(dir);
                var pluginAssemblyPath = Path.Combine(dir, pluginFolder + assemblyFileExtension);
                if (!File.Exists(pluginAssemblyPath))
                    continue;

                var pluginManifestFile = Path.Combine(dir, pluginManifestName);
                if (!File.Exists(pluginManifestFile))
                    continue;

                PluginInfo pluginInfo = null;
                using (var reader = new StreamReader(pluginManifestFile))
                {
                    string content = reader.ReadToEnd();
                    pluginInfo = JsonSerializer.Deserialize<PluginInfo>(content);
                }

                if (pluginInfo == null)
                    continue;

                var pluginLoadContext = new PluginLoadContext(pluginAssemblyPath);

                pluginInfo.Assembly = pluginLoadContext.LoadDefaultAssembly();
                pluginContext.Plugins.Add(pluginInfo);

                var partFactory = ApplicationPartFactory.GetApplicationPartFactory(pluginInfo.Assembly);
                foreach (var part in partFactory.GetApplicationParts(pluginInfo.Assembly))
                {
                    mvcBuilder.PartManager.ApplicationParts.Add(part);
                }

                // This piece finds and loads related parts, such as WebPlugin1.Views.dll
                var relatedAssembliesAttrs = pluginInfo.Assembly.GetCustomAttributes<RelatedAssemblyAttribute>();
                foreach (var attr in relatedAssembliesAttrs)
                {
                    var assembly = pluginLoadContext.LoadFromAssemblyName(new AssemblyName(attr.AssemblyFileName));
                    partFactory = ApplicationPartFactory.GetApplicationPartFactory(assembly);
                    foreach (var part in partFactory.GetApplicationParts(assembly))
                    {
                        mvcBuilder.PartManager.ApplicationParts.Add(part);
                    }
                }
            }

            mvcBuilder.Services.AddSingleton(pluginContext);

            return mvcBuilder;
        }
        /// <summary>
        /// Load existing plugin assembly
        /// </summary>
        /// <param name="pluginPath">Path for loading the plugin assembly</param>
        /// <returns>Assembly or null</returns>
        static Assembly LoadPlugin(string pluginPath)
        {
            // An assembly is the compiled output of your code, typically a DLL. It's the smallest unit of deployment for any .NET project.
            PluginLoadContext loadContext = new PluginLoadContext(pluginPath);

            // check if file is available/exists
            if (File.Exists(pluginPath))
            {
                return(loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginPath))));
            }
            else
            {
                return(null);
            }
        }
Ejemplo n.º 9
0
        protected IList <TPluginType> LoadDataPluginsFromDlls <TPluginType>(string[] pluginPaths)
            where TPluginType : class, IBasePlugin
        {
            var loadedPlugins = new List <TPluginType>();

            foreach (var pluginPath in pluginPaths)
            {
                _logger.LogInformation($"Loading Data plugins from {pluginPath}.");
                PluginLoadContext loadContext = new PluginLoadContext(pluginPath);
                var pluginAssembly            = loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginPath)));
                loadedPlugins.AddRange(LoadDataPluginsFromAssembly <TPluginType>(pluginAssembly));
            }

            _logger.LogInformation("Loading plugins completed.");
            return(loadedPlugins);
        }
Ejemplo n.º 10
0
        static Assembly LoadPlugin(string relativePath)
        {
            // Navigate up to the solution root
            string root = Path.GetFullPath(Path.Combine(
                                               Path.GetDirectoryName(
                                                   Path.GetDirectoryName(
                                                       Path.GetDirectoryName(
                                                           Path.GetDirectoryName(
                                                               Path.GetDirectoryName(typeof(Program).Assembly.Location)))))));

            string pluginLocation = Path.GetFullPath(Path.Combine(root, relativePath.Replace('\\', Path.DirectorySeparatorChar)));

            Console.WriteLine($"Loading commands from: {pluginLocation}");
            PluginLoadContext loadContext = new PluginLoadContext(pluginLocation);

            return(loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation))));
        }
        public static List <Assembly> LoadPluginAssembliesFromPath(string path)
        {
            List <Assembly> assemblies = new List <Assembly>();

            foreach (var assemblyDirectory in Directory.EnumerateDirectories(path, "*", SearchOption.TopDirectoryOnly))
            {
                var directoryName     = Path.GetDirectoryName(assemblyDirectory);
                var pluginDLLLocation = Directory.EnumerateFiles(assemblyDirectory, $"{directoryName}.dll", SearchOption.AllDirectories).FirstOrDefault();

                if (pluginDLLLocation != null)
                {
                    System.Diagnostics.Debug.WriteLine($"Loading Assembly: {pluginDLLLocation}");
                    PluginLoadContext loadContext = new PluginLoadContext(pluginDLLLocation);
                    var pluginAssembly            = loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginDLLLocation)));
                    assemblies.Add(pluginAssembly);
                }
            }

            return(assemblies);
        }
Ejemplo n.º 12
0
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (false && env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler(configure =>
                {
                    configure.Run(async context =>
                    {
                        context.Response.StatusCode          = (int)HttpStatusCode.InternalServerError;
                        context.Response.ContentType         = "text/plain";
                        IExceptionHandlerPathFeature feature = context.Features.Get <IExceptionHandlerPathFeature>();
                        Exception exception = feature?.Error;

                        if (exception != null)
                        {
                            await context.Response.WriteAsync("### Exception ###\n");
                            await context.Response.WriteAsync($"{nameof(Exception.Message)}:{exception.Message}\n");
                            await context.Response.WriteAsync($"{nameof(Exception.Source)}:{exception.Source}\n");
                            await context.Response.WriteAsync($"{nameof(Exception.StackTrace)}\n{exception.StackTrace}");
                            while (exception.InnerException != null)
                            {
                                exception = exception.InnerException;
                                await context.Response.WriteAsync("\n### InnerException ###\n");
                                await context.Response.WriteAsync($"{nameof(Exception.Message)}:{exception.Message}\n");
                                await context.Response.WriteAsync($"{nameof(Exception.Source)}:{exception.Source}");
                            }
                        }
                    });
                });
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.Map("/{**action}", async context =>
                {
                    string action = context.Request.Path;

                    if (string.IsNullOrEmpty(action))
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        context.Response.Headers.Add(X_ERROR_MESSAGE, nameof(action));
                        return;
                    }

                    if ('\\' == Path.DirectorySeparatorChar)
                    {
                        action = action.Replace('/', Path.DirectorySeparatorChar);
                    }

                    if (action.StartsWith(Path.DirectorySeparatorChar))
                    {
                        action = action.Remove(0, 1);
                    }

                    action = Path.Combine(AppContext.BaseDirectory, "actions", $"{action}.xml");

                    if (!File.Exists(action))
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        context.Response.Headers.Add(X_ERROR_MESSAGE, action);
                        return;
                    }

                    XmlDocument xml = new XmlDocument();
                    xml.Load(action);

                    XmlNode root = xml.SelectSingleNode("actions");

                    if (root?.HasChildNodes != true)
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        context.Response.Headers.Add(X_ERROR_MESSAGE, action);
                        return;
                    }

                    object data = null;

                    foreach (XmlNode act in root.ChildNodes)
                    {
                        string plugin = act.Attributes[nameof(plugin)]?.Value;
                        if (string.IsNullOrEmpty(plugin))
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                            context.Response.Headers.Add(X_ERROR_MESSAGE, nameof(plugin));
                            return;
                        }

                        string invoke = act.Attributes[nameof(invoke)]?.Value;
                        if (string.IsNullOrEmpty(invoke))
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                            context.Response.Headers.Add(X_ERROR_MESSAGE, nameof(invoke));
                            return;
                        }

                        if (!plugin.StartsWith(IPlugin.NAMESPACE))
                        {
                            plugin = $"{IPlugin.NAMESPACE}.{plugin}";
                        }

                        string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins", plugin, $"{plugin}.dll");

                        if (!File.Exists(file))
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                            context.Response.Headers.Add(X_ERROR_MESSAGE, file);
                            return;
                        }

                        PluginLoadContext loader = new PluginLoadContext(file);
                        Assembly assembly        = loader.LoadFromAssemblyName(new AssemblyName(plugin));

                        if (assembly == null)
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                            context.Response.Headers.Add(X_ERROR_MESSAGE, plugin);
                            return;
                        }


                        invoke = $"{plugin}.{invoke}";

                        IPlugin instance = assembly.CreateInstance(invoke) as IPlugin;

                        if (instance == null)
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                            context.Response.Headers.Add(X_ERROR_MESSAGE, invoke);
                            return;
                        }

                        int result = await instance.ExecuteAsync(context, act, data, x => { data = x; }).ConfigureAwait(true);

                        loader?.Unload();

                        if (result != 0)
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                            context.Response.Headers.Add(X_ERROR_MESSAGE, $"{invoke}:{result}");
                            return;
                        }
                    }
                    ;
                });
            });
        }