.net - 如何注册通用对象工厂?

标签 .net generics autofixture open-generics

我有以下两个类(class):

public class KeyedEntity<TEntity>
{
    internal KeyedEntity() { }

    public Identifier Key { get; set; }
    public TEntity Entity { get; set; }
}

public static class KeyedEntity
{
    public static KeyedEntity<TEntity> Create<TEntity>(Identifier key, TEntity entity)
    {
        return new KeyedEntity<TEntity>
        {
            Key = key,
            Entity = entity,
        };
    }
}

构造函数的原因是internal第二类存在是我想强制执行更具高度可维护性的 KeyedEntity.Create(x, y)语法而不是 new KeyedEntity<T>{ Key = x, Entity = y } 。 (请注意,类型是使用以前的语法推断的。)

我想告诉 AutoFixture 如何创建 KeyedEntity 的实例。然而,Register方法似乎只允许注册单一类型而不是开放的泛型类型。

如何注册KeyedEntity.Create<TEntity>作为 KeyedEntity<TEntity> 的创建函数?

最佳答案

为了支持您的开放通用类型,您可以编写自定义样本生成器:

public class KeyedEntityBuilder : ISpecimenBuilder
{
    private readonly static MethodInfo createMethod =
        typeof(KeyedEntity).GetMethod("Create");

    public object Create(object request, ISpecimenContext context)
    {
        var t = request as Type;
        if (t == null ||
            !t.IsGenericType ||
            t.GetGenericTypeDefinition() != typeof(KeyedEntity<>))
            return new NoSpecimen(request);

        var entityType = t.GetGenericArguments().Single();

        var key = context.Resolve(typeof(Identifier));
        var entity = context.Resolve(entityType);

        return createMethod
            .MakeGenericMethod(entityType)
            .Invoke(null, new[] { key, entity });
    }
}

(为了清楚起见,省略了防御性编码。)

以下单元测试通过:

public class Tests
{
    [Fact]
    public void CreateKeyedEntity()
    {
        var fixture = new Fixture();
        fixture.ResidueCollectors.Add(new KeyedEntityBuilder());

        var actual = fixture.Create<KeyedEntity<Foo>>();

        Assert.NotNull(actual.Key);
        Assert.NotNull(actual.Entity);
    }
}

为了更好的可维护性,您应该封装 KeyedEntityBuilder in a Customization .

关于.net - 如何注册通用对象工厂?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20209469/

相关文章:

scala - 有没有办法创建一个具有作为类型参数子类型的特征或混合的泛型类

c# - 在 AutoFixture 中创建复杂的子项时使用父属性的值

c# - 在此上下文中没有响应

c# - 需要使用数据库表架构在 .net 中获取空数据表

.net - Roslyn C# 编译器如何知道在哪里可以找到 .NET 程序集文件?

java - 令人困惑的 Java 泛型用法 : how do I properly parameterize this?

generics - 为什么在具有泛型类型参数的结构定义中使用特征边界?

c# - 事实与理论的区别? - xUnit.net

unit-testing - 为什么 AutoFixture 自定义会导致未填充继承的属性?

.net - 找出 .NET 中的总磁盘空间和可用磁盘空间