在程序集内创建动态假 class
Creating a dynamic fake class inside of an assembly
可能我问的是不可能的,但这是我的问题和问题。首先这是 C# 和 .NET。
我想定义一个 class 到接口的空实现(空方法,返回默认值的函数),如果我更改接口,我将不需要调整代码。不幸的是,我无法生成包含程序集的实现,也无法在其上定义动态模拟,因为实例化是通过反射自动完成的。这是更广泛解释的问题:
我有一个 dll/assembly 让我们称它为 IMyInterface.dll,它包含一个接口:IMyInterface。
上面的层我在单独的 dll/assembly 中有实现,我们称它为 MyInterfaceImplementation.dll.
在 middle/between 中,我有一个自动化测试框架,它可以依赖于 IMyInterface.dll 但不依赖于 MyInterfaceImplementation.dll.
现在这个测试框架使用通过反射实例化类型的生产代码基础设施。它是一个依赖注入类型的框架。
所以你对生产代码基础结构说给我这个程序集的这个接口实现。
在我们的例子中,你说给我一个来自 MyInterfaceImplementation.dll 的 IMyInterface。
在测试框架中,您不能依赖 MyInterfaceImplementation,因此您可以在第三个程序集中基于 IMyInterface 定义 fake/stub/mock class 让我们称之为:MyInterfaceFakeImplementation.dll
在测试框架中,你说从 MyInterfaceFakeImplementation.dll 给我一个 IMyInterface 就可以了。
注意:对于我们的模块层次结构,不可能重组依赖关系。关于模拟框架,我不控制实例化。实例化是在依赖注入框架内完成的。
当你在 MyInterfaceFakeImplementation.dll 中编写代码时,你会这样写:
class MyInterfaceFakeImplementation : IMyInterface
{
// IMyInterface implementation.
}
现在我想提供的是动态的class IMyInterface,所以当界面变化时我不需要适配假的。
我想要的很矮:
鉴于:
IMyInterface.dll
中的IMyInterface界面
MyInterfaceFakeImplementation.dll
中 IMyInterface 的 MyInterfaceFakeImplementation 实现
MyInterfaceFakeImplementation 具有空函数和 returns 默认值。
时间:
我更改 IMyInterface(例如更改函数签名)。
然后:
我不需要更改 MyInterfaceFakeImplementation,只需重新编译 MyInterfaceFakeImplementation.dll。注意:不可能生成这个程序集,需要编译。
这是一个解决方法。
在 IMyInterface.dll 中的 IMyInterface 旁边做一个伪实现 (class),让我们称之为 MyInterfaceFakeBase。
在 MyInterfaceFakeImplementation.dll 中,从这个基础 class MyInterfaceFakeBase 派生 MyInterfaceFakeImplementation 并将其留空。
更改接口 (IMyInterface) 时适配 MyInterfaceFakeBase 并且永远不用担心 MyInterfaceFakeImplementation 和 MyInterfaceFakeImplementation.dll.
Okie,对于那些想在这里开始编码的人来说,这里有一个示例控制台类型的应用程序,可能会有所帮助。将 class 添加到此代码,以便它找到实现接口的类型,如果更改接口,则不需要更改 class。 (不要修改 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);
}
}
}
}
}
再见
拉斯洛
嗯,没有人回答,所以不可能做这样的事情。
可以在运行时为接口创建动态装饰器或代理或模拟,或者生成具有接口伪实现的程序集,但不是我想要的方式。 C#、.NET、CLR 不允许。或者更好地说,C# 不允许这种动态(解释)行为是一件好事。
您可以使用类型转发来声明类型移入运行时生成的程序集(请参阅 assemblybuilder),您可以在其中发出您的类型(请参阅 typebuilder)。
可能我问的是不可能的,但这是我的问题和问题。首先这是 C# 和 .NET。
我想定义一个 class 到接口的空实现(空方法,返回默认值的函数),如果我更改接口,我将不需要调整代码。不幸的是,我无法生成包含程序集的实现,也无法在其上定义动态模拟,因为实例化是通过反射自动完成的。这是更广泛解释的问题:
我有一个 dll/assembly 让我们称它为 IMyInterface.dll,它包含一个接口:IMyInterface。
上面的层我在单独的 dll/assembly 中有实现,我们称它为 MyInterfaceImplementation.dll.
在 middle/between 中,我有一个自动化测试框架,它可以依赖于 IMyInterface.dll 但不依赖于 MyInterfaceImplementation.dll.
现在这个测试框架使用通过反射实例化类型的生产代码基础设施。它是一个依赖注入类型的框架。
所以你对生产代码基础结构说给我这个程序集的这个接口实现。
在我们的例子中,你说给我一个来自 MyInterfaceImplementation.dll 的 IMyInterface。
在测试框架中,您不能依赖 MyInterfaceImplementation,因此您可以在第三个程序集中基于 IMyInterface 定义 fake/stub/mock class 让我们称之为:MyInterfaceFakeImplementation.dll
在测试框架中,你说从 MyInterfaceFakeImplementation.dll 给我一个 IMyInterface 就可以了。
注意:对于我们的模块层次结构,不可能重组依赖关系。关于模拟框架,我不控制实例化。实例化是在依赖注入框架内完成的。
当你在 MyInterfaceFakeImplementation.dll 中编写代码时,你会这样写:
class MyInterfaceFakeImplementation : IMyInterface
{
// IMyInterface implementation.
}
现在我想提供的是动态的class IMyInterface,所以当界面变化时我不需要适配假的。
我想要的很矮:
鉴于:
IMyInterface.dll
中的IMyInterface界面
MyInterfaceFakeImplementation.dll
中 IMyInterface 的 MyInterfaceFakeImplementation 实现
MyInterfaceFakeImplementation 具有空函数和 returns 默认值。
时间:
我更改 IMyInterface(例如更改函数签名)。
然后:
我不需要更改 MyInterfaceFakeImplementation,只需重新编译 MyInterfaceFakeImplementation.dll。注意:不可能生成这个程序集,需要编译。
这是一个解决方法。
在 IMyInterface.dll 中的 IMyInterface 旁边做一个伪实现 (class),让我们称之为 MyInterfaceFakeBase。
在 MyInterfaceFakeImplementation.dll 中,从这个基础 class MyInterfaceFakeBase 派生 MyInterfaceFakeImplementation 并将其留空。
更改接口 (IMyInterface) 时适配 MyInterfaceFakeBase 并且永远不用担心 MyInterfaceFakeImplementation 和 MyInterfaceFakeImplementation.dll.
Okie,对于那些想在这里开始编码的人来说,这里有一个示例控制台类型的应用程序,可能会有所帮助。将 class 添加到此代码,以便它找到实现接口的类型,如果更改接口,则不需要更改 class。 (不要修改 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);
}
}
}
}
}
再见 拉斯洛
嗯,没有人回答,所以不可能做这样的事情。 可以在运行时为接口创建动态装饰器或代理或模拟,或者生成具有接口伪实现的程序集,但不是我想要的方式。 C#、.NET、CLR 不允许。或者更好地说,C# 不允许这种动态(解释)行为是一件好事。
您可以使用类型转发来声明类型移入运行时生成的程序集(请参阅 assemblybuilder),您可以在其中发出您的类型(请参阅 typebuilder)。