使用CSharpCodeProvider.CompileAssemblyFromSource时如何引用运行项目中的接口?
When using CSharpCodeProvider.CompileAssemblyFromSource how reference an interface in the running project?
我有一些代码 运行 并在运行时生成接口的实现。我正在尝试使用 CSharpCodeProvider
但是当我尝试编译具有 class 实现接口的代码时 运行 应用程序的相同代码(在调试中为 运行 Visual Studio 中的模式),它会抛出异常:
"The type or namespace name 'TestCodeGen' could not be found (are you missing a using directive or an assembly reference?)"
我的代码:
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Web.Http;
using Microsoft.CodeDom.Providers.DotNetCompilerPlatform;
namespace TestCodeGen
{
public class TestApp
{
public static void Main(string[] args)
{
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = true;
parameters.OutputAssembly = "MyImpl";
CompilerResults results = provider.CompileAssemblyFromSource(
parameters,
@"
using TestCodeGen;
public class MyImpl : IInterface
{
public string GetName()
{
return ""test"";
}
}
"
);
IInterface impl = (IInterface) Activator.CreateInstance(null, "MyImpl");
System.Diagnostics.Debug.WriteLine(impl.GetName());
}
}
public interface IInterface
{
string GetName();
}
}
如何添加对我的界面及其命名空间的引用?有什么方法可以使用 parameters.ReferencedAssemblies.Add("WHAT_GOES_HERE?");
?
您需要添加对包含 IInterface
的程序集的引用。您可以使用 typeof(IInterface).Assembly.Location
.
要创建 MyImpl
的实例,您首先需要使用 results.CompiledAssembly.GetType("MyImpl")
获取类型
using System;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
public class TestApp
{
public static void Main(string[] args)
{
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = true;
parameters.OutputAssembly = "MyImpl";
parameters.ReferencedAssemblies.Add(typeof(IInterface).Assembly.Location);
CompilerResults results = provider.CompileAssemblyFromSource(
parameters,
@"
public class MyImpl : IInterface
{
public string GetName()
{
return ""test"";
}
}
"
);
var myImplType = results.CompiledAssembly.GetType("MyImpl");
IInterface impl = (IInterface)Activator.CreateInstance(myImplType);
System.Diagnostics.Debug.WriteLine(impl.GetName());
}
}
public interface IInterface
{
string GetName();
}
我有一些代码 运行 并在运行时生成接口的实现。我正在尝试使用 CSharpCodeProvider
但是当我尝试编译具有 class 实现接口的代码时 运行 应用程序的相同代码(在调试中为 运行 Visual Studio 中的模式),它会抛出异常:
"The type or namespace name 'TestCodeGen' could not be found (are you missing a using directive or an assembly reference?)"
我的代码:
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Web.Http;
using Microsoft.CodeDom.Providers.DotNetCompilerPlatform;
namespace TestCodeGen
{
public class TestApp
{
public static void Main(string[] args)
{
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = true;
parameters.OutputAssembly = "MyImpl";
CompilerResults results = provider.CompileAssemblyFromSource(
parameters,
@"
using TestCodeGen;
public class MyImpl : IInterface
{
public string GetName()
{
return ""test"";
}
}
"
);
IInterface impl = (IInterface) Activator.CreateInstance(null, "MyImpl");
System.Diagnostics.Debug.WriteLine(impl.GetName());
}
}
public interface IInterface
{
string GetName();
}
}
如何添加对我的界面及其命名空间的引用?有什么方法可以使用 parameters.ReferencedAssemblies.Add("WHAT_GOES_HERE?");
?
您需要添加对包含 IInterface
的程序集的引用。您可以使用 typeof(IInterface).Assembly.Location
.
要创建 MyImpl
的实例,您首先需要使用 results.CompiledAssembly.GetType("MyImpl")
using System;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
public class TestApp
{
public static void Main(string[] args)
{
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = true;
parameters.OutputAssembly = "MyImpl";
parameters.ReferencedAssemblies.Add(typeof(IInterface).Assembly.Location);
CompilerResults results = provider.CompileAssemblyFromSource(
parameters,
@"
public class MyImpl : IInterface
{
public string GetName()
{
return ""test"";
}
}
"
);
var myImplType = results.CompiledAssembly.GetType("MyImpl");
IInterface impl = (IInterface)Activator.CreateInstance(myImplType);
System.Diagnostics.Debug.WriteLine(impl.GetName());
}
}
public interface IInterface
{
string GetName();
}