【发布时间】:2015-08-20 14:43:00
【问题描述】:
可能我要问的是不可能的,但这是我的问题和疑问。首先是 C# 和 .NET。
我想以这样的方式将类的空实现(空方法,返回默认值的函数)定义为接口,如果我更改接口,则不需要调整代码。不幸的是,我无法生成包含程序集的实现,也无法在其上定义动态模拟,因为实例化是通过反射自动完成的。这是更广泛地解释的问题:
我有一个 dll/程序集,我们称之为 IMyInterface.dll,其中包含一个接口:IMyInterface。
上面的层我在单独的 dll/程序集中实现了让我们称之为 MyInterfaceImplementation.dll。
在中间/之间,我有一个自动化测试框架,它可以依赖于 IMyInterface.dll 但不依赖于 MyInterfaceImplementation.dll。
现在这个测试框架使用了通过反射实例化类型的生产代码基础设施。它是一个依赖注入类型的框架。
所以你对生产代码基础设施说,从这个程序集中给我这个接口实现。
在我们的例子中,你说给我一个来自 MyInterfaceImplementation.dll 的 IMyInterface。
在测试框架中,您不能依赖 MyInterfaceImplementation,因此您可以在第三个程序集中定义一个基于 IMyInterface 的假/存根/模拟类,让我们称之为:MyInterfaceFakeImplementation.dll
在测试框架中,你说给我一个来自 MyInterfaceFakeImplementation.dll 的 IMyInterface,你很好。
注意:对于我们的模块层次结构,不可能重构依赖关系。关于模拟框架,我没有控制实例化。实例化在依赖注入框架内完成。
当您在 MyInterfaceFakeImplementation.dll 中编写代码时,您可以这样写:
class MyInterfaceFakeImplementation : IMyInterface
{
// IMyInterface implementation.
}
现在我想提供的是IMyInterface的动态类,所以当接口发生变化时,我不需要适应假的。
我想要的很短:
鉴于:
IMyInterface.dll 中的 IMyInterface 接口
MyInterfaceFakeImplementation.dll中IMyInterface的MyInterfaceFakeImplementation实现
MyInterfaceFakeImplementation 有空函数并返回默认值。
时间:
我更改了 IMyInterface(例如更改函数签名)。
然后:
我不需要更改 MyInterfaceFakeImplementation,只需重新编译 MyInterfaceFakeImplementation.dll。注意:无法生成此程序集,需要编译。
这是一种解决方法。
在 IMyInterface.dll 中的 IMyInterface 旁边做一个假实现(类),我们称之为 MyInterfaceFakeBase。
在 MyInterfaceFakeImplementation.dll 中,从这个基类 MyInterfaceFakeBase 派生 MyInterfaceFakeImplementation 并将其留空。
改变接口时(IMyInterface)适配MyInterfaceFakeBase,不用担心MyInterfaceFakeImplementation和MyInterfaceFakeImplementation.dll。
好的,对于那些想从这里开始编码的人来说,这是一个示例控制台类型的应用程序,它可能会有所帮助。向此代码添加一个类,以便它找到实现接口的类型,如果您更改接口,则无需更改该类。 (不要修改 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);
}
}
}
}
}
再见 拉斯洛
【问题讨论】:
-
您知道Mocking 用于单元测试的框架,对吧?他们或多或少和你描述的完全一样。
-
抱歉拼错了,有点问题:我不能在它上面定义动态模拟,因为实例化是通过反射自动完成的。需要让这一点更加明显。
-
尽管我理解你的问题和限制,但我会要求你修改它,并且不要以多种方式重复问题场景多次..
-
好吧,你是个非凡的人。 :-)
标签: c# .net dynamic reflection .net-assembly