我有以下两个类(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/