private static AssemblyLoadContext CreateLoadContext(string assemblyPath, Core.ILogger logger = null)
        {
            var validatedPath = ValidateFilePath(assemblyPath, logger);

            if (validatedPath == null)
            {
                return(null);
            }

            var mainAssemblyName = Path.GetFileNameWithoutExtension(validatedPath);
            var builder          = new AssemblyLoadContextBuilder();

            // Set base directory.
            var baseDir = Path.GetDirectoryName(validatedPath);

            builder.SetBaseDirectory(baseDir);
            logger?.LogTrace($"Base directory: '{baseDir}'");

            // Add deps file as a source for finding dependencies.
            var depsJsonFile = Path.Combine(baseDir, $"{mainAssemblyName}.deps.json");

            if (File.Exists(depsJsonFile))
            {
                builder.AddDependencyContext(depsJsonFile);
                logger?.LogTrace($"Added '{depsJsonFile}' as a deps file dependency");
            }

            // Add runtimeconfig file as a source for finding dependencies.
            var pluginRuntimeConfigFile = Path.Combine(baseDir, $"{mainAssemblyName}.runtimeconfig.json");

            builder.TryAddAdditionalProbingPathFromRuntimeConfig(pluginRuntimeConfigFile, includeDevConfig: true, out _);

            return(builder.Build());
        }
        private static AssemblyLoadContext CreateLoadContext(
            string baseDir,
            PluginConfig config,
            Type[] sharedTypes)
        {
            var depsJsonFile = Path.Combine(baseDir, config.MainAssembly.Name + ".deps.json");

            var builder = new AssemblyLoadContextBuilder();

            if (File.Exists(depsJsonFile))
            {
                builder.AddDependencyContext(depsJsonFile);
            }

            builder.SetBaseDirectory(baseDir);

            foreach (var ext in config.PrivateAssemblies)
            {
                builder.PreferLoadContextAssembly(ext);
            }

            if (sharedTypes != null)
            {
                foreach (var type in sharedTypes)
                {
                    builder.PreferDefaultLoadContextAssembly(type.Assembly.GetName());
                }
            }

            var runtimeConfigFile = Path.Combine(baseDir, config.MainAssembly.Name + ".runtimeconfig.json");

            builder.TryAddAdditionalProbingPathFromRuntimeConfig(runtimeConfigFile, includeDevConfig: true, out _);

            return(builder.Build());
        }
Пример #3
0
        private static AssemblyLoadContextBuilder CreateLoadContextBuilder(PluginConfig config)
        {
            var builder = new AssemblyLoadContextBuilder();

            builder.SetMainAssemblyPath(config.MainAssemblyPath);

            foreach (var ext in config.PrivateAssemblies)
            {
                builder.PreferLoadContextAssembly(ext);
            }

            if (config.PreferSharedTypes)
            {
                builder.PreferDefaultLoadContext(true);
            }

#if FEATURE_UNLOAD
            if (config.IsUnloadable || config.EnableHotReload)
            {
                builder.EnableUnloading();
            }

            if (config.EnableHotReload)
            {
                builder.PreloadAssembliesIntoMemory();
            }
#endif

            foreach (var assemblyName in config.SharedAssemblies)
            {
                builder.PreferDefaultLoadContextAssembly(assemblyName);
            }

#if !FEATURE_NATIVE_RESOLVER
            // In .NET Core 3.0, this code is unnecessary because the API, AssemblyDependencyResolver, handles parsing these files.
            var baseDir          = Path.GetDirectoryName(config.MainAssemblyPath);
            var assemblyFileName = Path.GetFileNameWithoutExtension(config.MainAssemblyPath);

            var depsJsonFile = Path.Combine(baseDir, assemblyFileName + ".deps.json");
            if (File.Exists(depsJsonFile))
            {
                builder.AddDependencyContext(depsJsonFile);
            }

            var pluginRuntimeConfigFile = Path.Combine(baseDir, assemblyFileName + ".runtimeconfig.json");

            builder.TryAddAdditionalProbingPathFromRuntimeConfig(pluginRuntimeConfigFile, includeDevConfig: true, out _);

            // Always include runtimeconfig.json from the host app.
            // in some cases, like `dotnet test`, the entry assembly does not actually match with the
            // runtime config file which is why we search for all files matching this extensions.
            foreach (var runtimeconfig in Directory.GetFiles(AppContext.BaseDirectory, "*.runtimeconfig.json"))
            {
                builder.TryAddAdditionalProbingPathFromRuntimeConfig(runtimeconfig, includeDevConfig: true, out _);
            }
#endif

            return(builder);
        }
Пример #4
0
        private static AssemblyLoadContext CreateLoadContext(
            string baseDir,
            PluginConfig config,
            Type[] sharedTypes,
            PluginLoaderOptions loaderOptions)
        {
            var depsJsonFile = Path.Combine(baseDir, config.MainAssembly.Name + ".deps.json");

            var builder = new AssemblyLoadContextBuilder();

            if (File.Exists(depsJsonFile))
            {
                builder.AddDependencyContext(depsJsonFile);
            }

            builder.SetBaseDirectory(baseDir);

            foreach (var ext in config.PrivateAssemblies)
            {
                builder.PreferLoadContextAssembly(ext);
            }

            if (loaderOptions.HasFlag(PluginLoaderOptions.PreferSharedTypes))
            {
                builder.PreferDefaultLoadContext(true);
            }

#if FEATURE_UNLOAD
            if (loaderOptions.HasFlag(PluginLoaderOptions.IsUnloadable))
            {
                builder.EnableUnloading();
            }
#endif

            if (sharedTypes != null)
            {
                foreach (var type in sharedTypes)
                {
                    builder.PreferDefaultLoadContextAssembly(type.Assembly.GetName());
                }
            }

            var pluginRuntimeConfigFile = Path.Combine(baseDir, config.MainAssembly.Name + ".runtimeconfig.json");

            builder.TryAddAdditionalProbingPathFromRuntimeConfig(pluginRuntimeConfigFile, includeDevConfig: true, out _);

            // Always include runtimeconfig.json from the host app.
            // in some cases, like `dotnet test`, the entry assembly does not actually match with the
            // runtime config file which is why we search for all files matching this extensions.
            foreach (var runtimeconfig in Directory.GetFiles(AppContext.BaseDirectory, "*.runtimeconfig.json"))
            {
                builder.TryAddAdditionalProbingPathFromRuntimeConfig(runtimeconfig, includeDevConfig: true, out _);
            }

            return(builder.Build());
        }
Пример #5
0
        public static AssemblyLoadContextBuilder AddDependencyContextWithCompileDeps(this AssemblyLoadContextBuilder builder, string depsFilePath)
        {
            var reader = new DependencyContextJsonReader();

            using (var file = File.OpenRead(depsFilePath))
            {
                var deps = reader.Read(file);
                builder.SetBaseDirectory(Path.GetDirectoryName(depsFilePath));
                builder.AddDependencyContext(deps);
                builder.AddCompileDependencies(deps);
            }
            return(builder);
        }