在程序集中创建动态伪类
本文关键字:动态 创建 集中 程序 程序集 | 更新日期: 2023-09-27 17:53:47
可能我问的是不可能的,但这是我的问题和问题。首先是c#和。net。
我想定义一个类的空实现(空方法,函数返回默认值),以这样的方式,如果我改变接口,我将不需要调整代码。不幸的是,我不能生成包含程序集的实现,也不能在其上定义动态模拟,因为实例化是通过反射自动完成的。下面是对这个问题更广泛的解释:
我有一个dll/程序集,我们叫它IMyInterface.dll,它包含一个接口:IMyInterface.dll。
在上面的层,我在一个单独的dll/程序集中实现,让我们称之为MyInterfaceImplementation.dll。
在中间/之间,我有一个自动化的测试框架,它可以依赖于IMyInterface.dll,但不依赖于MyInterfaceImplementation.dll。
现在,这个测试框架使用通过反射实例化类型的生产代码基础结构。它是一个依赖注入类型的框架。所以你对生产代码基础结构说,从这个程序集给我这个接口实现。
在我们的例子中,你说从MyInterfaceImplementation.dll给我一个IMyInterface。在测试框架中,你不能依赖于MyInterfaceImplementation,所以你在第三个程序集中定义了一个基于IMyInterface的fake/stub/mock类,我们称之为:MyInterfaceFakeImplementation.dll
在测试框架中,你说从MyInterfaceFakeImplementation.dll中给我一个IMyInterface,你就没事了。
注意:在我们的模块层次结构中,不可能重构依赖关系。关于模拟框架,我不控制实例化。实例化是在依赖注入框架内完成的。
当你在MyInterfaceFakeImplementation.dll中编写代码时,你这样写:
class MyInterfaceFakeImplementation : IMyInterface
{
// IMyInterface implementation.
}
现在我想提供的是动态类的IMyInterface,所以当接口改变时,我不需要适应假的
非常短,这是我想要的:
给:
IMyInterface.dll中的接口
MyInterfaceFakeImplementation在MyInterfaceFakeImplementation.dll中的IMyInterface实现
MyInterfaceFakeImplementation函数为空,返回默认值。
:
我更改了IMyInterface(例如,更改了函数签名)。
:
我不需要改变MyInterfaceFakeImplementation,只需重新编译MyInterfaceFakeImplementation.dll。注意:可能无法生成此程序集,需要编译。
这是一个解决方法。
在IMyInterface.dll中,在IMyInterface.dll的旁边做一个伪实现(类),让我们称之为MyInterfaceFakeBase。在MyInterfaceFakeImplementation.dll中,从这个基类MyInterfaceFakeBase派生MyInterfaceFakeImplementation,并将其保留为空。当改变接口(IMyInterface)适应MyInterfaceFakeBase,永远不要担心MyInterfaceFakeImplementation和MyInterfaceFakeImplementation.dll。
ok,对于那些想要开始编码的人来说,这里有一个示例控制台类型的应用程序,可能会有所帮助。在此代码中添加一个类,以便它找到实现接口的类型,并且如果更改接口,则不需要更改该类。(不要修改Main函数)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace DynamicFake3
{
public interface IMyInterface
{
void SimpleMethod();
bool SimpleFunction();
void OneParameterMethod(int i);
}
class Program
{
static void Main(string[] args)
{
Assembly anAssembly = Assembly.LoadFrom("DynamicFake3.exe");
foreach (Type aType in anAssembly.GetTypes())
{
if (aType.GetInterfaces().Contains(typeof(IMyInterface)))
{
Console.WriteLine(aType.FullName);
}
}
}
}
}
再见Laszlo
没有人回答这个问题,所以这样做是不可能的。可以在运行时为接口创建动态装饰器、代理或模拟,也可以生成具有接口虚假实现的程序集,但这不是我想要的方式。c#, . net, CLR不允许。或者更好地说,c#不允许这种动态(解释)行为是一件好事。
您可以使用类型转发来声明移动到运行时生成的程序集中的类型(请参阅assemblybuilder),在该程序集中您可以发出您的类型(请参阅typebuilder)。