在程序集中创建动态假类 [英] Creating a dynamic fake class inside of an assembly

查看:92
本文介绍了在程序集中创建动态假类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能我要问的是不可能的,但是这里是我的问题。首先是C#和.NET。

如果要更改接口,我想定义一个类的空实现(空方法,返回默认值的函数)到接口。无需修改代码。不幸的是,我无法生成包含程序集的实现,也无法在其上定义动态模拟,因为实例化是通过反射自动完成的。这是更广泛解释的问题:



我有一个dll /程序集,让我们称它为IMyInterface.dll,它包含一个接口:IMyInterface。

以上各层我在单独的dll /程序集中实现,让我们将其称为MyInterfaceImplementation.dll。

在中间/中间,我有一个自动化的测试框架,该框架可以依赖IMyInterface。 dll,但不在MyInterfaceImplementation.dll上。

现在,此测试框架使用生产代码基础结构,该结构通过反射实例化类型。这是一个依赖注入类型的框架。
因此,您对生产代码基础结构说,可以从此程序集中给我此接口实现。

在我们的案例中,您说给我一个来自MyInterfaceImplementation.dll的IMyInterface。
在测试框架中,您不能依赖MyInterfaceImplementation,因此您在第三个程序集中基于IMyInterface定义了一个假/存根/模拟类,可以将其命名为:MyInterfaceFakeImplementation.dll

在测试框架中您说从MyInterfaceFakeImplementation.dll给我一个IMyInterface,就可以了。

注意:对我们的模块层次结构,无法重新构造依赖关系。关于Mock框架,我不控制实例化。实例化是在依赖项注入框架内完成的。



当您在MyInterfaceFakeImplementation.dll中编写代码时,您会这样写下:

  class MyInterfaceFakeImplementation:IMyInterface 
{
// IMyInterface实现。
}

现在我想提供的是IMyInterface的动态类,所以当



非常简短,这就是我想要的:



给定:
IMyInterface.dll中的
IMyInterface接口

MyInterfaceFakeImplementation.dll中IMyInterface的MyInterfaceFakeImplementation实施

MyInterfaceFakeImplementation具有空函数并返回默认值。 / p>

何时:

我更改IMyInterface(例如,更改函数签名)。



然后:

我不需要更改MyInterfaceFakeImplementation,只需重新编译MyInterfaceFakeImplementation.dll。注意:不可能生成此程序集,需要对其进行编译。



这是一种解决方法。

执行伪实现(类)在IMyInterface.dll中的IMyInterface旁边,让我们将其称为MyInterfaceFakeBase。
在MyInterfaceFakeImplementation.dll中,从该基类MyInterfaceFakeBase派生MyInterfaceFakeImplementation并将其留空。
更改接口(IMyInterface)时,请改用MyInterfaceFakeBase,而不必担心MyInterfaceFakeImplementation和MyInterfaceFakeImplementation.dll。



Okie,对于那些想要在此处开始编码的人来说,可能有用的示例控制台类型应用程序。在此代码中添加一个类,以便它找到实现该接口的类型,并且如果您更改接口,则无需更改该类。 (不要修改Main函数。)

 使用系统; 
使用System.Collections.Generic;
使用System.Linq;
使用System.Reflection;
使用System.Text;
使用System.Threading.Tasks;

命名空间DynamicFake3
{
公共接口IMyInterface
{
void SimpleMethod();
bool SimpleFunction();
void OneParameterMethod(int i);
}

类程序
{
static void Main(string [] args)
{

Assembly anAssembly = Assembly .LoadFrom( DynamicFake3.exe);

foreach(在anAssembly.GetTypes()中输入aType)
{
if(aType.GetInterfaces()。Contains(typeof(IMyInterface)))
{
Console.WriteLine(aType.FullName);
}
}
}
}
}

再见
Laszlo

解决方案

没有人回答,所以不可能做这样的事情。
可以在运行时为接口创建动态装饰器或代理或模拟,也可以生成具有伪接口实现的程序集,但我不希望这样。 C#、. NET,CLR不允许这样做。或者更好地说,C#不允许这种动态的(解释的)行为是一件好事。


Probably what I am asking is impossible, but nevertheless here is my problem and question. First of all this is C# and .NET.
I would like to define an empty implementation (empty methods, functions returning defaults) of a class to an interface in such a way if I change the interface I will not need to adapt the code. Unfortunately I can not generate the implementation containing assembly and I can not define a dynamical mock on it because instantiation is done automatically via reflection. Here is the problem explained more broadly:

I have a dll/assembly let us call it IMyInterface.dll that contains an interface: IMyInterface.
Layers above I have the implementation in a separate dll/assembly let us call it MyInterfaceImplementation.dll.
In the middle/between I have an automatized test framework that can depend on IMyInterface.dll but not on MyInterfaceImplementation.dll.
Now this test framework uses the production code infrastructure that instantiates types via reflection. It is a dependency injection type framework. So you say to the production code infrastructure give me this interface implementation from this assembly.
In our case you say give me a IMyInterface from MyInterfaceImplementation.dll. In the test framework you can not depend from MyInterfaceImplementation so you define a fake/stub/mock class based on IMyInterface in a third assembly lets call it: MyInterfaceFakeImplementation.dll
In the test framework you say give me a IMyInterface from MyInterfaceFakeImplementation.dll and you are fine.
Note: Do to our modules hierarchy it is not possible to restructure the dependencies. Regarding Mock Frameworks, I am not controlling the instantiation. Instantiation is done inside the dependency injection framework.

When you write your code in the MyInterfaceFakeImplementation.dll you write down like this:

class MyInterfaceFakeImplementation : IMyInterface 
{
  // IMyInterface implementation. 
}

Now what I would like is to provide is dynamic class of IMyInterface, so when interface changes than I do not need to adapt the fake.

Very shorty here is what I want:

Given:
IMyInterface interface in IMyInterface.dll
MyInterfaceFakeImplementation impementation of IMyInterface in MyInterfaceFakeImplementation.dll
MyInterfaceFakeImplementation has empty functions and returns default values.

When:
I change IMyInterface (Ex. change a functions signature).

Then:
I do not need to change MyInterfaceFakeImplementation, just recompile MyInterfaceFakeImplementation.dll. Note: It is not possible to possible to generate this assembly, needs to be compiled.

Here is a workaround.
Do a fake implementation (class) next to IMyInterface in the IMyInterface.dll, let us call it MyInterfaceFakeBase. In the MyInterfaceFakeImplementation.dll derive the MyInterfaceFakeImplementation from this base class MyInterfaceFakeBase and leave it empty. When changing the interface (IMyInterface) adapt MyInterfaceFakeBase and never worry about MyInterfaceFakeImplementation and MyInterfaceFakeImplementation.dll.

Okie, for those who would like start coding here is a sample Console type App that, might help. Add a class to this code so that it finds a type that implements the interface and if you change the interface you do not need to change that class. (Do not modify Main function.)

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);
                }
            }
        }
    }
}

Bye Laszlo

解决方案

Well nobody answered it so it is impossible to do something like this. It is possible to create a dynamic decorator or proxy or mock for an interface during runtime or to generate an assembly that has a fake implementation for an interface, but not how I would like it. C#, .NET, CLR does not allows it. Or better said it is a good thing that C# does not allow such dynamical (interpreted) behavior.

这篇关于在程序集中创建动态假类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆