标签:c reference assemblies dynamically-generated
我正在C#教自己中间语言(IL)生成,而且我已经陷入了几个小时的困境 – 这对于如何引用System.Windows.Forms.dll几乎是好几天了例如)来自动态程序集,我使用AppDomain.CurrentDomain.DefineDynamicAssembly和System.Reflection.Emit …基于最优秀的例子在http://olondono.blogspot.com/2008/02/creating-code-at-runtime.html生成
我有一个基本的TransferObjectDllGenerator工作,但现在我想从(仅)生成的程序集中引用现有的库,并且无法弄清楚如何.
This SO question引导我进入AppDomain.CurrentDomain.AssemblyResolve事件.我尝试实现一个事件处理程序,但它永远不会被触发,所以我想我已经做了一些基本上愚蠢的事情,比如把事件处理程序放在完全错误的地方?
任何指向正确方向的人都会非常感激.
这是我的主线……有趣的位是//<< - 这样评论
using System;
using System.Reflection;
//using System.Windows.Forms; (and removed the project's Reference to System.Windows.Forms)
namespace ILGen
{
/// <summary>
/// Generates .\bin\$whatever\PersonLibrary.dll containing MSIL equivalent to:
/// namespace PersonLibrary {
/// public class Person {
/// public string FirstName { get; set; }
/// public string LastName { get; set; }
/// public Person() { }
/// public Person(string firstname, string lastname) {
/// FirstName = firstname;
/// LastName = lastname;
/// }
/// } //end-class
/// } //end-namespace
/// </summary>
public class Program
{
public static void Main(String[] args) {
AppDomain.CurrentDomain.AssemblyResolve += MyAssemblyResolver; // <<-- Hook the "resolve this assembly" event.
try {
var dll = new TransferObjectDllGenerator("PersonLibrary");
dll.AddClass("Person", new[] {
new Property("FirstName", typeof(string))
, new Property("LastName", typeof(string))
, new Property("OK", Type.GetType("System.Windows.Forms.Button")) // <<-- References System.Windows.Forms.dll; Type.GetType returns null.
});
Console.WriteLine("Generated: " + dll.Save());
} finally {
AppDomain.CurrentDomain.AssemblyResolve -= MyAssemblyResolver; // <<-- Unhook the "resolve this assembly" event.
}
}
static Assembly MyAssemblyResolver(object sender, ResolveEventArgs args) // <<-- Handle the "resolve this assembly" event.
{
if ( args.Name.StartsWith("System.Windows.Forms.") ) // <<-- Breakpoint here, which is never reached.
return Assembly.LoadFrom(@"C:\Windows\winsxs\msil_system.windows.forms_b77a5c561934e089_6.0.6001.22230_none_1a2132e45d2f30fc\System.Windows.Forms.dll");
return null;
}
} // end-class
} // end-namespace
如果您需要/想要TransferObjectDllGenerator代码,请大声说…我还没有发布它,因为它有点太大(恕我直言)的论坛帖子.
在此先感谢您的时间.
干杯.基思.
编辑:为将来找到此主题的任何人提供一个工作示例.
无需提供自定义AssemblyResolve事件处理程序.那是一个phurphy.我们只需要提供程序集的完全限定名称……其中一个具有程序集名称,命名空间,版本和GUID.
using System;
using System.Reflection;
namespace ILGen
{
public class Program
{
public static void Main(String[] args) {
var dll = new TransferObjectDllGenerator("PersonLibrary");
// We need to provide the fully-qualified-assembly-name to
// make the standard assembly-resolver search the GAC.
// Thanks to Julien Lebosquain for pointing this out.
Type buttonType = Type.GetType(
"System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
dll.AddClass("Person", new[] {
new Property("FirstName", typeof(string))
, new Property("LastName", typeof(string))
, new Property("OK", buttonType)
});
Console.WriteLine("Generated: " + dll.Save());
}
} // end-class
} // end-namespace
解决方法:
未指定程序集名称的Type.GetType将仅搜索当前程序集和mscorlib中的类型名称.
尝试使用AssemblyQualifiedName
的类型.这里是.NET 4:
Type.GetType("System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
默认解析程序将在GAC和应用程序域专用路径中进行搜索,因此您无需执行任何操作即可获得所需的行为.如果你必须自定义分辨率,那么AssemblyResolve或new Type.GetType
overload在.NET 4中采用解析器功能是可行的方法.请注意,从GAC或winsxs路径手动解析通常是一个坏主意:让框架执行其解析作业.
标签:c,reference,assemblies,dynamically-generated 来源: https://codeday.me/bug/20190621/1254108.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。