gpt4 book ai didi

c# - 根据上下文为抽象属性创建具体类型

转载 作者:太空狗 更新时间:2023-10-29 22:26:17 25 4
gpt4 key购买 nike

我有以下类型层次结构:

public abstract class ResourceId
{
}

public class CarId : ResourceId
{
}

public class PlaneId: ResourceId
{
}

public interface IResource
{
ResourceId Id { get; set; }
}

public class Plane : IResource
{
public ResourceId Id { get; set; }
}

public class Car : IResource
{
public ResourceId Id { get; set; }
}

我希望 AutoFixture 在尝试创建飞机或汽车时创建“正确”类型的 ResourceId。

我尝试使用:

_fixture.Customize<Plane>(composer => 
composer.With(h => h.Id, _fixture.Create<PlaneId>()));

当然,这会为每个实例创建相同的 ID。我希望每个人都有一个唯一的 ID。

最好的方法是什么?

最佳答案

有一种方法可以满足您的要求,但它需要一个鲜为人知 的自定义 API: Register 方法。

Register的目的|是允许用户为特定类型指定一个工厂函数。然后,AutoFixture 会将创建该类型的对象委托(delegate)给该函数。

Register 的一个显着特征是它能够提供匿名对象以在需要时作为参数传递给工厂函数。它通过许多重载来实现。这里是a few examples :

  • Register<T>(Func<T> factory)不向工厂提供任何参数
  • Register<T1, T>(Func<T1, T> factory)提供一个 T1 类型的参数创建 T 类型的对象
  • Register<T1, T2, T>(Func<T1, T2, T> factory)提供两个 T1 类型的参数和 T2创建 T 类型的对象

现在,我们可以使用这个特性来定制Car类型对象的方式。和 Plane通过分配 CarId 的匿名实例创建和 PlanId到他们的 Id属性:

[Fact]
public void Test()
{
var fixture = new Fixture();
fixture.Register<CarId, Car>(id =>
{
var resource = new Car { Id = id };
return resource;
});
fixture.Register<PlaneId, Plane>(id =>
{
var resource = new Plane { Id = id };
return resource;
});

Assert.NotSame(fixture.Create<Car>().Id, fixture.Create<Car>().Id);
Assert.NotSame(fixture.Create<Plane>().Id, fixture.Create<Plane>().Id);
}

这个测试通过是因为 CarIdPlanId传递给工厂函数的对象由 AutoFixture 创建,因此每次都不一样。

关于c# - 根据上下文为抽象属性创建具体类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25498791/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com