我一直在使用ROWLEX库来处理RDF-s。它附带了一个名为OwlGrinder.exe的设计时GUI工具,它可以从我的OWL本体生成C#帮助程序类(确切地说是.NET程序集)。我想知道是否有人知道我是否可以在运行时以编程方式执行相同操作。
答案 0 :(得分:4)
ROWLEX刚刚成为开源的,所以现在你有机会真正查看OwlGrinder.exe的代码并从那里复制代码。但是,这是一个简短的例子:
private NC3A.SI.Rowlex.AssemblyGenerator generator;
private void RunAssemblyGeneration(XmlDocument ontologyFileInRdfXml)
{
this.generator = new NC3A.SI.Rowlex.AssemblyGenerator();
this.generator.GenerateAsync(ontologyFileInRdfXml, "myAssemblyName",
null, this.OnGenerationFinished);
}
private void OnGenerationFinished(string errorMessage)
{
if (errorMessage == null)
{
// Success
// Displaying warnings and saving result
string[] warnings = this.generator.Warnings;
this.generator.SaveResult(@"C:\myAssemblyName.dll");
// Important! One generator instance can be executed only once.
this.generator = null;
this.RejoiceOverSuccess();
}
else
{
// Failure
this.MournOverFailure();
}
}
如果要在运行时生成程序集,我假设您可能希望根据用户的要求反复重复该程序集。你必须注意这里,因为.NET不允许你卸载程序集。因此,您无法摆脱先前运行的程序集。解决方案是您每次都可以在可以卸载的新AppDomain中执行生成代码。 OwlGrinder.exe就是这样做的,你可能希望在MainForm.cs中达到峰值
答案 1 :(得分:2)
是的,Lame先生,您可以以编程方式生成.NET代码。
有几种选择。
将代码创建为文本 您可以在应用程序中编译任何.cs或.vb源文件。有关启动程序,请参阅Microsoft.CSharp.CSharpCodeProvider类的帮助。您以编程方式调用编译器,指定要嵌入的资源,放置生成的程序集的位置,依赖项等。这里的一个场景是使用template.cs文件,在其中嵌入更多代码,然后编译它。结果是由该代码生成的程序集(.dll或.exe或.netmodule,如果您愿意)。然后,您可以使用反射加载该程序集并调用它。
使用文档对象模型创建代码 这里的相关功能区域称为“CodeDom”,它的工作方式类似于网页的HTML DOM,除了文档对象模型用于创建.NET代码。以编程方式使用DOM元素构造代码。
CodeDom的例子:
var class1 = new System.CodeDom.CodeTypeDeclaration(className);
class1.IsClass=true;
class1.TypeAttributes = System.Reflection.TypeAttributes.Public;
class1.Comments.Add(new System.CodeDom.CodeCommentStatement("This class has been programmatically generated"));
// add a constructor to the class
var ctor= new System.CodeDom.CodeConstructor();
ctor.Attributes = System.CodeDom.MemberAttributes.Public;
ctor.Comments.Add(new System.CodeDom.CodeCommentStatement("the null constructor"));
class1.Members.Add(ctor);
// add one statement to the ctor: an assignment
// in code it will look like; _privateField = new Foo();
ctor.Statements.Add(new System.CodeDom.CodeAssignStatement(new System.CodeDom.CodeVariableReferenceExpression("_privateField"), new System.CodeDom.CodeObjectCreateExpression(fooType)));
// include a private field into the class
System.CodeDom.CodeMemberField field1;
field1= new System.CodeDom.CodeMemberField();
field1.Attributes = System.CodeDom.MemberAttributes.Private;
field1.Name= "_privateField";
field1.Type=new System.CodeDom.CodeTypeReference(fooType);
class1.Members.Add(field1);
等等。您可以添加常规方法,代码中的各种语句,等等。 AFAIK CodeDom的东西支持语言支持的一切。你可以做lambdas和linq表达式,条件和控制流,任何东西。
然后,您可以编译该类,并再次生成一个程序集,您可以将其保存到磁盘或保留在内存中并动态加载。