Skip to content

Netcore dependecy managament #24

Closed
@viferga

Description

@viferga

For Netcore 1.x (and maybe 2.x) it is possible to properly handle dependencies (not sure if it is involved with the current fail when loading.

Current error:
The type 'Console' exists in both 'System.Console, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' and 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'

...
"Microsoft.Extensions.DependencyModel": "2.1.0",
...

using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.DependencyModel.Resolution;

        internal sealed class AssemblyResolver : IDisposable
        {
            private ICompilationAssemblyResolver assemblyResolver;
            private DependencyContext dependencyContext;
            private AssemblyLoadContext loadContext;

            public AssemblyResolver(MemoryStream stream)
            {
                this.Assembly = AssemblyLoadContext.Default.LoadFromStream(stream);
                this.Dependency(Environment.GetEnvironmentVariable("LOADER_SCRIPT_PATH"));
            }

            public AssemblyResolver(AssemblyName assemblyName)
            {
                this.Assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(assemblyName);
                this.Dependency(Environment.GetEnvironmentVariable("LOADER_SCRIPT_PATH"));
            }

            public AssemblyResolver(string path)
            {
                this.Assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(path);
                this.Dependency(path);
            }

            public Assembly Assembly { get; }

            public void Dispose()
            {
                this.loadContext.Resolving -= this.OnResolving;
            }

            private void Dependency(string path)
            {
                this.dependencyContext = DependencyContext.Load(this.Assembly);

                this.assemblyResolver = new CompositeCompilationAssemblyResolver(new ICompilationAssemblyResolver[]
                {
                    new AppBaseCompilationAssemblyResolver(Path.GetDirectoryName(path)),
                    new ReferenceAssemblyPathResolver(),
                    new PackageCompilationAssemblyResolver()
                });

                this.loadContext = AssemblyLoadContext.GetLoadContext(this.Assembly);
                this.loadContext.Resolving += OnResolving;
            }

            private Assembly OnResolving(AssemblyLoadContext context, AssemblyName name)
            {
                RuntimeLibrary library = this.dependencyContext.RuntimeLibraries.FirstOrDefault(runtime =>
                    string.Equals(runtime.Name, name.Name, StringComparison.OrdinalIgnoreCase));

                if (library != null)
                {
                    var wrapper = new CompilationLibrary(
                        library.Type,
                        library.Name,
                        library.Version,
                        library.Hash,
                        library.RuntimeAssemblyGroups.SelectMany(g => g.AssetPaths),
                        library.Dependencies,
                        library.Serviceable);

                    var assemblies = new List<string>();
                    this.assemblyResolver.TryResolveAssemblyPaths(wrapper, assemblies);
                    if (assemblies.Count > 0)
                    {
                        return this.loadContext.LoadFromAssemblyPath(assemblies[0]);
                    }
                }

                return null;
            }
        }

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions