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

问题描述

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

I'm making a console app on .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 its 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 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:\Location\Of\" + "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:

你好,约翰·道伊

快速说明:
方法 Load 的覆盖无关紧要您最好将其内容替换为并抛出新的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核心控制台应用程序的文件夹中加载程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 09:05