C# 在运行时生成接口实现
我想问一下,是否有一个库允许在运行时生成接口的实现,并具有下面所示的一些附加功能 假设我有这样的界面:C# 在运行时生成接口实现,c#,mvvm,castle-windsor,interceptor,proxy-classes,C#,Mvvm,Castle Windsor,Interceptor,Proxy Classes,我想问一下,是否有一个库允许在运行时生成接口的实现,并具有下面所示的一些附加功能 假设我有这样的界面: interface ICustomer { string Name {get;set;} string IAddress { get;set; } } interface IAddress { string Street {get;set;} } ICustomer customer = someLibrary.Create<ICustomer>(boo
interface ICustomer
{
string Name {get;set;}
string IAddress { get;set; }
}
interface IAddress
{
string Street {get;set;}
}
ICustomer customer = someLibrary.Create<ICustomer>(bool createSubObjects)
我想这样做:
interface ICustomer
{
string Name {get;set;}
string IAddress { get;set; }
}
interface IAddress
{
string Street {get;set;}
}
ICustomer customer = someLibrary.Create<ICustomer>(bool createSubObjects)
有什么好主意吗?也许像这样的方法会奏效:
public T Create<T>(bool createSubObjects)
{
T MyICustomer = default(T);
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append(@"
using System;
using System.Collections.Generic;
using System.Linq;
namespace MyNameSpace
{
public class RuntimeCustomer:NotifyPropertyChanged,").Append(typeof(T).FullName).Append(@"
{
string name;").Append(createSubObjects ? @"
IAddress address = new RuntimeAddress(); " :@"
IAddress address = null;").Append(@"
public string Name
{
get { return name; }
set { SetProperty(ref name, value); }
}
public IAddress Address
{
get { return address; }
set { SetProperty(ref address, value) }
}
}
class RuntimeAddress : NotifyPropertyChanged, IAddress
{
string street;
public string Street
{
get { return street; }
set { SetProperty(ref,street, value) }
}
}
}");
Dictionary<string, string> providerOptions = new Dictionary<string, string>();
providerOptions["CompilerVersion"] = "v3.5"; //OR YOUR VERSION
Microsoft.CSharp.CSharpCodeProvider provider = new Microsoft.CSharp.CSharpCodeProvider(providerOptions);
System.CodeDom.Compiler.CompilerParameters parameters = new System.CodeDom.Compiler.CompilerParameters();
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = true;
parameters.IncludeDebugInformation = true;
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add(typeof(System.Linq.Enumerable).Assembly.Location);
parameters.ReferencedAssemblies.Add(System.Reflection.Assembly.GetCallingAssembly().Location);
parameters.ReferencedAssemblies.Add(System.Reflection.Assembly.GetExecutingAssembly().Location);
System.CodeDom.Compiler.CompilerResults results = provider.CompileAssemblyFromSource(parameters, sb.ToString());
if (results.Errors.Count == 0)
{
Type generated = results.CompiledAssembly.GetType("MyNameSpace.RuntimeAddress");
MyICustomer = (T)generated.GetConstructor(Type.EmptyTypes).Invoke(null);
}
else
{
//Do something
}
return MyICustomer;
}
public T创建(bool createSubObjects)
{
T MyicCustomer=默认值(T);
System.Text.StringBuilder sb=新的System.Text.StringBuilder();
某人附加(@)
使用制度;
使用System.Collections.Generic;
使用System.Linq;
名称空间MyNameSpace
{
公共类RuntimeCustomer:NotifyPropertyChanged,“).Append(typeof(T).FullName).Append(@”
{
字符串名称;“”。追加(createSubObjects?@)
IAddress address=新运行时地址();“:@”
IadAddress=null;“”。追加(@)
公共字符串名
{
获取{返回名称;}
set{SetProperty(ref name,value);}
}
公开演说
{
获取{返回地址;}
set{SetProperty(ref地址,值)}
}
}
类运行时地址:NotifyPropertyChanged,IAddress
{
弦街;;
公共弦街
{
获取{返回街;}
set{SetProperty(ref,street,value)}
}
}
}");
Dictionary providerOptions=新建字典();
providerOptions[“CompilerVersion”]=“v3.5”;//或您的版本
Microsoft.CSharp.CSharpCodeProvider provider=新的Microsoft.CSharp.CSharpCodeProvider(providerOptions);
System.CodeDom.Compiler.CompilerParameters parameters=new System.CodeDom.Compiler.CompilerParameters();
parameters.GenerateExecutable=false;
parameters.GenerateInMemory=true;
parameters.includedebuginfo=true;
parameters.referencedAssembly.Add(“System.dll”);
parameters.referencedAssembly.Add(typeof(System.Linq.Enumerable).Assembly.Location);
parameters.ReferencedAssembly.Add(System.Reflection.Assembly.GetCallingAssembly().Location);
parameters.ReferencedAssembly.Add(System.Reflection.Assembly.GetExecutionGassembly().Location);
System.CodeDom.Compiler.CompilerResults results=provider.compileasemblyFromSource(参数,sb.ToString());
如果(results.Errors.Count==0)
{
生成的类型=results.CompiledAssembly.GetType(“MyNameSpace.RuntimeAddress”);
MyicCustomer=(T)生成的.GetConstructor(Type.EmptyTypes).Invoke(null);
}
其他的
{
//做点什么
}
返回我的客户;
}
作为一种选择,您可以自己伪造。它将完成所有这些,甚至更多,而不需要发出你自己的IL。看见
只需获取它并向类中添加属性,或从INotifyPropertyChanged派生。正如jure所说,您可以使用DynamicProxy实现此功能,但它将应用于接口的JIT实现。看看这个: PostSharp也擅长此用例,但它是通过编译时编织和运行时JIT来完成的
希望这有帮助也许像这样@jure你能举例说明在这种情况下如何使用它吗?我以前看过Castle和LinFu,但没发现对那个案子有用谢谢你的回答。我相信这样的IL发射或编译是必须的,您的代码可以很好地工作,但是这个接口只包含示例,所以我认为一些库是以通用方式这样做的exists@user2542183您可以创建自己的库,并通过将代码文本作为参数传递给create函数使其更加灵活。因为必须在某个地方定义某个接口的实现。投赞成票或打分作为回答:)?哦,是的,我最终会的,但我希望这样的事情已经存在