不能把握冻结/喷射/注册的区别 [英] Can't grasp the difference between Freeze/Inject/Register

查看:184
本文介绍了不能把握冻结/喷射/注册的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在开始之前,我AutoFixture的忠实粉丝,我仍然在学习如何使用工具的曲线。所以感谢已经开发Autofixture Ploeh先生和所有的贡献者。

Before starting, I'm a big fan of AutoFixture, I'm still in the curve of learning how to use the tool. So thanks for having developed Autofixture Mr Ploeh and all the contributors.

因此​​,让我们开始与我的问题。

So let's start with my question.


AutoFixture / AutoMoq忽略注入实例/冷冻模拟​​

上面的链接有趣的部分是有这个代码

The interesting part of the above link is given this code

Mock<ISettings> settingsMock = new Mock<ISettings>();
settingsMock.Setup(s => s.Get(settingKey)).Returns(xmlString);

ISettings settings = settingsMock.Object;
fixture.Inject(settings);

要哪个马克回答这个问题可以改写为

To which Mark answer it can be rewritten to

fixture.Freeze<Mock<ISettings>>()
       .Setup(s => s.Get(settingKey)).Returns(xmlString);



它看起来像一个syntaxic糖,采用冻结法是一种在流畅的界面创建写模拟,配置,并在autofixture容器注入。

It looks like a syntaxic sugar, using Freeze method is a way to write in fluent interface the creation of the mock, the configuration, and the injection in autofixture container.

在网络上做一些研究之后,实际上是冻结并注入之间的功能差异。我发现这个问题:
https://github.com/AutoFixture/AutoFixture/issues/59
答案它指向
我怎么能冻结AutoFixture 一个空实例

After doing some research on the web, there're actually a functional difference between Freeze and Inject. I found this question: https://github.com/AutoFixture/AutoFixture/issues/59 which point the answer to How can I Freeze a null instance in AutoFixture

上面的链接的作者描述的方法冻结如下:

The author of the link above describe Freeze method as the following:

在内部,冻结创建请求的类的实例(如:
IPayPalConfiguration),然后注入它,所以它总是返回
的实例时我们再次请求它

Internally, Freeze creates an instance of the requested type (e.g. IPayPalConfiguration) and then injects it so it will always return that instance when you request it again

据我了解,当我们做

var customer = fixture.Freeze<Order>();



它总是用命令的同一个实例,只要我们的代码请求判令类型。但是,如果我在,我希望它使用一个特定的实例冻结构造函数指定什么?

it will always use the same instance of Order whenever our code request an Order type. But what if I specify in Freeze constructor that I want it to use a specific instance ?

这里有一个小的代码示例:

Here's a little code example:

[Fact]
public void MethodeName()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());
    fixture.Freeze<OrderLine>(new OrderLine("Foo"));
    var order = fixture.Create<Order>();
}

public class Order
{
    private readonly OrderLine _line;

    public Order(OrderLine line)
    {
        _line = line;
    }
}
public class OrderLine
{
    private readonly string _name;

    public OrderLine(string name)
    {
        _name = name;
    }
}



应该不是订单行的名称等于富,而不是namefe48163a-d5a0-49a5-b349-7b11ba5f804b?冷冻方法的文档说:

Shouldn't the name of OrderLine be equal to "Foo" instead of namefe48163a-d5a0-49a5-b349-7b11ba5f804b ? The documentation of Freeze method say:

<typeparam name="T">The type to freeze.</typeparam>
<param name="fixture">The fixture.</param>
<param name="seed">Any data that adds additional information when creating the anonymous object. Hypothetically, this value might be the value being frozen, but this is not likely.</param>



为什么笔者不知道返回的值是什么时​​候?如果我指定的,我在冻结的构造函数实例,我期待autofixture使用这个实例?

why is the author not sure when the value is returned ? If I specify, my instance in the constructor of Freeze, I'm expecting autofixture to use this instance ?

然后

请注意到,不太可能被用作冻结值,除非你自定义的做到这一点。如果要注入特定的值到灯具,你应该使用方法instead.`

Please notice that the isn't likely to be used as the frozen value, unless you've customized to do this. If you wish to inject a specific value into the Fixture, you should use the method instead.`

好像我要定制种子参数。任何人都可以澄清?通过文档指出该解决方案是使用方法注入。事实上,它的工作原理与订单行我的代码示例。

It seems like I have to customize the seed parameter. Can anyone clarify ? The solution pointed by documentation is to use Inject method. And indeed, it works in my code example with OrderLine.

我在找你帮忙了解冻结,注入的区别,并且还注册,而根据源代码,只是通过注入方法调用,但它需要一个lambda。

I'm looking for your help to understand the difference between Freeze, Inject, and also Register which, according to the source code, is just called by Inject method but it takes a lambda.

推荐答案

注册并注入

曾几何时,没有注入并没有冻结; 注册统治的代码。

Once upon a time, there was no Inject and no Freeze; Register ruled the code.

然后返回,有一个注册超载正是如此定义的:

Back then, there was a Register overload defined thusly:

public static void Register<T>(this IFixture fixture, T item)

但是,它必须与此密切相关共享API:

However, it had to share the API with this close relative:

public static void Register<T>(this IFixture fixture, Func<T> creator)

AutoFixture的创造者认为这是很好的,但很可惜:用户遭受了与混乱。最惨重,用户可以写:

The creator of AutoFixture thought that this was good, but alas: users were stricken with confusion. Most grievously, a user could write:

fixture.Register(() => universe.LightUp());



but also

fixture.Register(universe.LightUp);



这意味着同样的事情,因为 universe.LightUp 是一个方法的引用,因而委托相匹配。

which means the exact same thing, because universe.LightUp is a reference to a method, and thus matches a delegate.

不过,该语法看起来像一个属性的参考,因此,如果 LightUp 一直是属性,而不是一种方法,第一个过载会由编译器进行选择。

However, that syntax looks like a property reference, so if LightUp had been a property instead of a method, the first overload would be selected by the compiler.

这引起了很大的混乱,因此注册< T>(这IFixture夹具,T项目)超载被重命名为注入< T>(这IFixture夹具,T项目)

This caused much confusion, so the Register<T>(this IFixture fixture, T item) overload was renamed to Inject<T>(this IFixture fixture, T item).

冻结

冻结有着不同的历史。很久很久以前,当我还是在命令式的方式使用AutoFixture,我注意到,我反复写了这样的代码:

Freeze has a different history. A long time ago, when I still used AutoFixture in an imperative way, I noticed that I repeatedly wrote code like this:

var foo = fixture.Create<Foo>();
fixture.Inject(foo);



所以我决定,这是一个概念,并把它命名为冻结的。在冻结方法仅适用于这些代码两行的简写。

So I decided that this was a concept and named it Freeze. The Freeze method is only shorthand for those two lines of code.

我我想找你帮忙了解冻结,注入的区别,并且还注册,而根据源代码,只是通过注入方法调用,但它需要一个lambda

I'm looking for your help to understand the difference between Freeze, Inject, and also Register which, according to the source code, is just called by Inject method but it takes a lambda

在一般情况下,它应该不会太难注入区分注册,因为它们的签名不碰撞。因此,如果你尝试完成一个目标使用这两种方法之一,而你的代码编译,你可能选择了正确的版本。

In general, it shouldn't be too hard to distinguish between Inject and Register, since their signatures don't collide. Thus, if you try to accomplish a goal with one of those two methods, and your code compiles, you probably chose the right version.

这也将是为案件冻结如果不是在OP中使用的过载:

This would also be the case for Freeze if it wasn't for the overload used in the OP:

[EditorBrowsable(EditorBrowsableState.Never)]
public static T Freeze<T>(this IFixture fixture, T seed)

注意这个超载居然有 EditorBrowsableState.Never ,因为它总是混淆的人。不过,虽然如此,但显然人们仍然发现超载,所以我觉得应该在AutoFixture 4 移动。它的存在,因为它是很容易实现...

Notice that this overload actually has EditorBrowsableState.Never, because it always confuses people. However, despite that, apparently people still find that overload, so I think it should be moved in AutoFixture 4. It's one of those features that exist because it was easy to implement...

这篇关于不能把握冻结/喷射/注册的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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