Vah*_*iri 35 .net c# .net-core .net-core-rc2
我正在.Net Core平台上制作一个控制台应用程序,并且想知道,如何使用C#动态功能加载程序集(.dll文件)和实例化类?它似乎与.Net 4.X有很大不同,并没有真正记录......
例如,假设我有一个类库(.Net Core),它只有一个类:
namespace MyClassLib.SampleClasses
{
public class Sample
{
public string SayHello(string name)
{
return $"Hello {name}";
}
public DateTime SayDateTime()
{
return DateTime.Now;
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,dll文件的名称将MyClassLib.dll
位于其中/dlls/MyClassLib.dll
.
现在我想在一个简单的控制台应用程序(.Net Core)中加载它并实例化Sample
该类并使用C#的动态功能在以下控制台应用程序中调用方法:
namespace AssemblyLoadingDynamic
{
public class Program
{
public static void Main(string[] args)
{
// load the assembly and use the classes
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意: .Net Core我指的是RC2版本.
Rob*_*Rob 37
目前针对netcoreapp1.0
您的运行实际上并不需要实现您自己的程度AssemblyLoader
.有一个Default
存在,工作得很好.(因此@ VSG24提到它Load
什么都不做).
using System;
using System.Runtime.Loader;
namespace AssemblyLoadingDynamic
{
public class Program
{
public static void Main(string[] args)
{
var myAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(@"C:\MyDirectory\bin\Custom.Thing.dll");
var myType = myAssembly.GetType("Custom.Thing.SampleClass");
var myInstance = Activator.CreateInstance(myType);
}
}
}
Run Code Online (Sandbox Code Playgroud)
用project.json
看起来像:
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
},
"System.Runtime.Loader": "4.0.0"
},
"frameworks": {
"netcoreapp1.0": {
"imports": "dnxcore50"
}
}
}
Run Code Online (Sandbox Code Playgroud)
Vah*_*iri 19
不确定这是否是最佳方式,但这是我想出的:
(仅在.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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
MyClassLib.SampleClasses
是名称空间,Sample
是类名称类名.
执行时,它会尝试SampleClassLib.dll
在内存中加载已编译的类库并让我的控制台应用程序访问MyClassLib.SampleClasses.Sample
(看看问题)然后我的应用程序调用该方法SayHello()
并将"John Doe"作为名称传递给它,因此程序打印:
"Hello John Doe"
快速说明:
该方法的覆盖Load
并不重要,因此您可能只需更换其内容,throw new NotImplementedException()
它不应影响我们关心的任何内容.
小智 10
谢谢你的分享.它也在使用Net Core 1.0.如果程序集在同一路径上需要另一个程序集,则可以使用下面的代码示例.
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using Microsoft.Extensions.DependencyModel;
public class AssemblyLoader : AssemblyLoadContext
{
private string folderPath;
public AssemblyLoader(string folderPath)
{
this.folderPath = folderPath;
}
protected override Assembly Load(AssemblyName assemblyName)
{
var deps = DependencyContext.Default;
var res = deps.CompileLibraries.Where(d => d.Name.Contains(assemblyName.Name)).ToList();
if (res.Count > 0)
{
return Assembly.Load(new AssemblyName(res.First().Name));
}
else
{
var apiApplicationFileInfo = new FileInfo($"{folderPath}{Path.DirectorySeparatorChar}{assemblyName.Name}.dll");
if (File.Exists(apiApplicationFileInfo.FullName))
{
var asl = new AssemblyLoader(apiApplicationFileInfo.DirectoryName);
return asl.LoadFromAssemblyPath(apiApplicationFileInfo.FullName);
}
}
return Assembly.Load(assemblyName);
}
}
Run Code Online (Sandbox Code Playgroud)
请记住将以下依赖项添加到您的project.json
文件中:
"System.Runtime.Loader"
"Microsoft.Extensions.DependencyModel"
Run Code Online (Sandbox Code Playgroud)
小智 6
使用.net core 1.1 / standard 1.6,我发现AssemblyLoader不可用,并且
AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyPath)给我一个“无法加载文件或程序集xxx”错误。
终于,下面的解决方案对我有用-纯粹通过添加一个步骤来获取AssemblyName对象。希望它能帮助任何陷入困境的人:
var assemblyName = AssemblyLoadContext.GetAssemblyName(assemblyPath); var assembly = Assembly.Load(assemblyName);
归档时间: |
|
查看次数: |
39307 次 |
最近记录: |