在程序集内创建动态假 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)。