当前位置: 首页 > 编程语言 > C#

在C#中为运行时接口创建一个类分享

时间:2023-04-11 02:03:31 C#

在C#中为运行时接口创建一个类我正在考虑使用一组对象,假设此时有3个对象存活,它们都实现一个公共接口,然后将这些对象包装在第四个对象中,该对象也实现了相同的接口。第四个对象的方法和属性的实现将简单地调用3个底层对象的相关位。我知道这里会有这样做没有意义的情况,但这是针对服务多播架构的,所以已经有一套很好的限制。我的问题是从哪里开始。第四个对象的生成应该在内存中,在运行时完成,所以我在想Reflection.Emit,不幸的是我没有足够的经验不知道从哪里开始。我必须在内存中构建程序集吗?它看起来确实如此,但我只想快速指示我应该从哪里开始。基本上我正在寻找一个接口,以及实现该接口的对象实例列表,并构建一个新对象,同时实现该接口,应该“多播”所有方法调用和对所有底层对象的属性访问,可能更少。异常会有很多问题,但我会在遇到它们时修复它们。这适用于面向服务的体系结构,我希望现有代码(例如,记录器服务)现在可以访问多个记录器服务,而无需更改使用这些服务的代码。相反,我希望运行时生成一个记录器服务包装器,它在内部简单地调用多个底层对象上的相关方法。这适用于.NET3.5和C#。(我在这里通过添加额外的上下文/信息来证明答案的合理性)是的,目前Reflection.Emit是解决这个问题的唯一方法。在.NET4.0中,Expression类已扩展为支持循环和语句块,因此对于单一方法的使用,编译的Expression是个好主意。但即使这样也不支持多方法接口(只是单一方法委托)。幸运的是,我以前做过;请参阅如何在C#中编写实现给定接口的通用容器类?如果有人感兴趣,我会在这里发布我自己的实现。这受到了马克的回答的影响和复制,我接受了。此代码可用于包装一组对象,所有这些对象都实现了一个公共接口,并且在一个新对象中,也实现了该接口。当访问返回对象的方法和属性时,以相同的方式访问基础对象的相应方法和属性。龙来了:这是有特定目的的。这可能是一个奇怪的问题,特别是因为代码不能确保所有底层对象都被赋予与被调用者传递的完全相同的对象(或者更确切地说,它不禁止底层对象之一弄乱参数),对于返回值方法,只返回最后一个返回值。至于out/ref参数,我什至没有测试它是如何工作的,但它可能不会。你被警告了。#region使用使用系统;使用System.Linq;使用系统诊断;使用System.Reflection;使用System.Reflection.Emit;使用LVK.Collections;#endregionnamespaceLVK.IoC{//////这个类实现了一个服务包装器,可以将多个服务包装到一个多播///服务中,然后将所有方法调用分派到所有底层服务中。/////////这段代码深受MarcGravell的实现的影响并从他///在StackOverflow上发布的实现复制而来:http://stackoverflow.com/questions/847809///publicstaticclassMulticastService{//////将指定服务包装在单个多播服务对象中。/////////实现多播服务的服务类型。/////////将所有方法调用多播到的底层服务对象。/////////多播服务实例。/////////一片空白。///-或-///包含空引用。/////////不是接口类型。///publicstaticTServiceWrap(paramsTService[]services)whereTService:class{return(TService)Wrap(typeof(TService),(Object[])services);}//////将指定的服务包装在单个多播服务对象中。/////////实现多播服务的服务接口对象。/////////将所有方法调用多播到的底层服务对象。/////////多播服务实例。/////////一片空白。///-或-///为空。///-或-///包含空引用。/////////不是接口类型。/////////中的一个或多个服务对象未实现///接口。///publicstaticObjectWrap(TypeserviceInterfaceType,paramsObject[]services){#region参数验证if(Object.ReferenceEquals(null,serviceInterfaceType))thrownewArgumentNullException("serviceInterfaceType");如果(!serviceInterfaceType.IsInterface)thrownewArgumentException("serviceInterfaceType");如果(Object.ReferenceEquals(null,services)||services.Length==0)thrownewArgumentNullException("services");foreach(varserviceinservices){if(Object.ReferenceEquals(null,service))thrownewArgumentNullException("services");if(!serviceInterfaceType.IsAssignableFrom(service.GetType()))thrownewInvalidOperationException("其中一个指定的服务没有实现指定的服务接口");}#endregionif(services.Length==1)returnservices[0];AssemblyNameassemblyName=newAssemblyName(String.Format("tmp_{0}",serviceInterfaceType.FullName));StringmoduleName=String.Format("{0}.dll",assemblyName.Name);Stringns=serviceInterfaceType.Namespace;如果(!String.IsNullOrEmpty(ns))ns+=".";varassembly=AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,AssemblyBuilderAccess.RunAndSave);varmodule=assembly.DefineDynamicModule(moduleName,false);变量type=module.DefineType(String.Format("{0}Multicast_{1}",ns,serviceInterfaceType.Name),TypeAttributes.Class|TypeAttributes.AnsiClass|TypeAttributes.Sealed|TypeAttributes.NotPublic);type.AddInterfaceImplementation(serviceInterfaceType);varar=Array.CreateInstance(serviceInterfaceType,services.Length);for(Int32index=0;indexdoesyoureallyneedtocreatetheassemblyatruntime?probablyyoudon'tneeditc#givesyouAction,yesoperatorandlambda/delegates...以上是C#学习教程:创建一个C#中运行时接口的类分享所有内容,如果对大家有用,还需要了解更多C#学习教程,希望大家多加关注——本文来自网络合集,不代表立场。如涉及侵权,请点击维权联系管理员删除,如需转载请注明出处: