我如何注册一个通用的对象工厂? [英] How can I register a generic object factory?
问题描述
我有以下两类:
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,
};
}
}
究其原因,构造函数是内部
第二类存在是我要执行更多的高维护 KeyedEntity.Create(X,Y )
语法,而不是新KeyedEntity&LT; T&GT; {键= X,实体= Y}
。 (请注意,类型推断与前者的语法。)
The reason the constructor is internal
and the second class exists is I want to enforce the more highly-maintainable KeyedEntity.Create(x, y)
syntax rather than new KeyedEntity<T>{ Key = x, Entity = y }
. (Note that the type is inferred with the former syntax.)
我想告诉AutoFixture如何创建 KeyedEntity
的实例。但是,注册
办法似乎只能允许一个单一类型的注册,而不是开放式泛型类型。
I want to tell AutoFixture how to create an instance of KeyedEntity
. However, the Register
method only seems to allow registration of a single type rather than an open generic type.
如何注册 KeyedEntity.Create&LT; TEntity&GT;
作为创建函数 KeyedEntity&LT; TEntity&GT;
How can I register KeyedEntity.Create<TEntity>
as the creation function for KeyedEntity<TEntity>
?
推荐答案
要支持你的开放式泛型类型,你可以写一个自定义的样本生成器的:
To support your open generic type, you can write a custom Specimen Builder:
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 });
}
}
(防御编码省略清晰。)
(Defensive coding omitted for clarity.)
下面的单元测试通过:
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
在自定义。
For better maintainability, you should encapsulate KeyedEntityBuilder
in a Customization.
这篇关于我如何注册一个通用的对象工厂?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!