控制台应用程序文件夹中的程序集

控制台应用程序文件夹中的程序集

本文介绍了如何加载位于 .NET Core 控制台应用程序文件夹中的程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 .NET Core 平台上制作一个控制台应用程序,想知道如何使用 C# 动态功能加载程序集(.dll 文件)和实例化类?它似乎与 .NET 4.X 大不相同,并且没有真正记录在案...

I'm making a console app on the .NET Core platform and was wondering, how does one load assemblies (.dll files) and instantiate classes using C# dynamic features? It seems so much different than .NET 4.X and it's not really documented...

例如,假设我有一个类库 (.NET Core) 并且它只有一个类:

For example, let's say I have a class library (.NET Core) and it has only one class:

namespace MyClassLib.SampleClasses
{
    public class Sample
    {
        public string SayHello(string name)
        {
            return $"Hello {name}";
        }

        public DateTime SayDateTime()
        {
            return DateTime.Now;
        }
    }
}

所以 dll 文件的名称将是 MyClassLib.dll,它位于 /dlls/MyClassLib.dll.

So the name of the dll file would be MyClassLib.dll and it's located in /dlls/MyClassLib.dll.

现在我想在一个简单的控制台应用程序 (.NET Core) 中加载它并实例化 Sample 类并在以下控制台应用程序中使用 C# 的动态特性调用方法:

Now I want to load this in a simple console app (.NET Core) and instantiate the Sample class and call the methods using dynamic features of C# in the following console app:

namespace AssemblyLoadingDynamic
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // load the assembly and use the classes
        }
    }
}

注意:.NET Core 是指 RC2 版本.

Note:By .NET Core, I mean the RC2 version.

推荐答案

不确定这是否是最好的方法,但我想到了:

Not sure if it's the best way to do it but here's what I came up with:

(仅在 .Net Core RC2 - Windows 上测试)

using System;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using Microsoft.Extensions.DependencyModel;

namespace AssemblyLoadingDynamic
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var asl = new AssemblyLoader();
            var asm = asl.LoadFromAssemblyPath(@"C:LocationOf" + "SampleClassLib.dll");

            var type = asm.GetType("MyClassLib.SampleClasses.Sample");
            dynamic obj = Activator.CreateInstance(type);
            Console.WriteLine(obj.SayHello("John Doe"));
        }

        public class AssemblyLoader : AssemblyLoadContext
        {
            // Not exactly sure about this
            protected override Assembly Load(AssemblyName assemblyName)
            {
                var deps = DependencyContext.Default;
                var res = deps.CompileLibraries.Where(d => d.Name.Contains(assemblyName.Name)).ToList();
                var assembly = Assembly.Load(new AssemblyName(res.First().Name));
                return assembly;
            }
        }
    }
}

MyClassLib.SampleClasses 是命名空间,Sample 是类型,也就是类名.

MyClassLib.SampleClasses is the namespace and Sample is the type aka class name.

执行时,它会尝试在内存中加载 SampleClassLib.dll 编译的类库,并让我的控制台应用程序访问 MyClassLib.SampleClasses.Sample(取一个看问题)然后我的应用程序调用方法 SayHello() 并将John Doe"作为名称传递给它,因此程序打印:

When executed, it will try to load the SampleClassLib.dll compiled class library in the memory and gives my console app access to MyClassLib.SampleClasses.Sample (take a look at the question) then my app calls the method SayHello() and passes "John Doe" as name to it, Therefore the program prints:

Hello John Doe"

快速说明:方法 Load 的覆盖无关紧要,因此您不妨将其内容替换为 throw new NotImplementedException() 并且它不应该影响我们关心的任何事情.

Quick note:The override for the method Load doesn't matter so you might as well just replace its content with throw new NotImplementedException() and it shouldn't affect anything we care about.

这篇关于如何加载位于 .NET Core 控制台应用程序文件夹中的程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 07:23