示例控制台程序.
class Program
{
static void Main(string[] args)
{
// ... code to build dll ... not written yet ...
Assembly assembly = Assembly.LoadFile(@"C:\dyn.dll");
// don't know what or how to cast here
// looking for a better way to do next 3 lines
IRunnable r = assembly.CreateInstance("TestRunner");
if (r == null) throw new Exception("broke");
r.Run();
}
}
Run Code Online (Sandbox Code Playgroud)
我想动态构建一个程序集(.dll),然后加载程序集,实例化一个类,并调用该类的Run()方法.我应该尝试将TestRunner类转换为某些东西吗?不确定一个程序集中的类型(动态代码)如何知道我的(静态程序集/ shell应用程序)中的类型.使用几行反射代码只在一个对象上调用Run()会更好吗?该代码应该是什么样的?
更新:威廉埃德蒙森 - 见评论
我需要在另一个appdomain中调用对象的方法(传递param并获得结果).想法?
UPD两个AppDomain都不是由我的代码创建的(主机应用程序创建它,然后我的代码被调用).如何从另一个AppDomain访问?
我有一些C#代码(让我们称之为"脚本")我在运行时编译.它使用我的主程序中的接口来访问其功能.编译完成后我就CompilerResults.CompiledAssembly可以了CreateInstance(Type).
一旦我完成了使用脚本,我想完全卸载.据我所知,如果我创建一个单独的应用程序域,我只能这样做:将 DLL加载到单独的AppDomain中
我有一些与我的实施有关的问题:
ReferencedAssemblies.Add(typeof(Interface).Assembly.Location)在编译之前正在做的事情.CompilerParameters GenerateInMemory=true,还是必须将其保存在某个地方?可能重复:将
DLL加载到单独的AppDomain中
将.NET程序集加载到单独的AppDomain中的正确方法是什么,这样您就可以访问其类型/类,但仍然可以卸载它(并重新加载它).
这是前面讨论的切线: C# - 正确加载程序集,查找类和调用Run()方法
好的,这是交易:
我想加载一个定义Assembly到我的用户AppDomain,但我只想在指定Assembly匹配某些要求时这样做.在我的情况下,除了其他要求之外,它必须具有我们可以调用的Assembly级别.AttributeMandatoryAssemblyAttribute
据我所知,我可以走两条路:
加载Assembly到我当前的AppDomain并检查是否Attribute存在.容易但不方便,因为我坚持装载的装配,即使它没有MandatoryAssemblyAttribute.不好.
我可以创建一个新的AppDomain并Assembly从那里加载并检查我的旧的MandatoryAddemblyAttribute是否存在.如果是,则转储创建的AppDomain并继续加载Assembly到我的CurrentAppDomain,如果没有,只需转储新的AppDomain,告诉用户,让他再试一次.
说起来容易做起来难.在网上搜索,我发现了几个关于如何解决这个问题的例子,包括在SO中发布的上一个问题:将DLL加载到单独的AppDomain中
我在这个解决方案中看到的问题是,您实际上必须知道Assembly要加载的类型(全名).这不是我喜欢的解决方案.重点是尝试插入Assembly符合某些要求的任意内容,并通过属性发现要使用的类型.事先没有知道Assembly将具有什么类型.当然,我可以要求Assembly以这种方式使用的任何意图应该实现一些虚拟类,以便为其提供"入口点" CreateInstanceFromAndUnwrap.我宁愿不.
另外,如果我继续沿着这条线做点什么:
using (var frm = new OpenFileDialog())
{
frm.DefaultExt = "dll";
frm.Title = "Select dll...";
frm.Filter = "Model files (*.dll)|*.dll";
answer = frm.ShowDialog(this);
if (answer == DialogResult.OK)
{
domain = AppDomain.CreateDomain("Model", …Run Code Online (Sandbox Code Playgroud) 我有一个C#应用程序,它与一些硬件(USB设备)连接,如下所示:
C# application -> intermediate DLL -> hardware DLL -> hardware.中间DLL和硬件DLL随USB设备一起提供,因此我无法控制它们.
该中间DLL是唯一我需要它这在VS的项目包括,因为这就是我所说的.然后硬件DLL位于同一目录中,因此必须自动找到.
现在,使用不同的硬件DLL发布了新版本的硬件设备.旧DLL与新硬件不兼容,新DLL与旧硬件不兼容.
如何使我的应用程序与两个硬件一起工作?我想我需要根据需要加载和卸载每个DLL?
c# ×6
.net ×3
assemblies ×3
appdomain ×2
reflection ×2
clr ×1
codedom ×1
dll ×1
dynamic ×1
ipc ×1