私は、指定された型のコンストラクタを探すためにリフレクションを使用しています。私はそのコンストラクタが次に必要な時にそれを使うことができるように、その型にキー設定されたコンストラクタをキャッシュしたいと思います。以下のコードはそうですが、オブジェクトを返すのと同じようにコンストラクタを格納し、それを目的の型にキャストする必要があります。より安全な型にする方法があることを期待していました。汎用ディクショナリの型制約
private static readonly ConcurrentDictionary<Type, Func<Guid, object>> AggregateConstructors = new ConcurrentDictionary<Type, Func<Guid, object>>();
public TAggregate GetAggregate<TAggregate>(Guid aggregateId) where TAggregate : AggregateRoot
{
var constructor = AggregateConstructors.GetOrAdd(typeof(TAggregate), GetConstructorFunc<TAggregate>());
// Requires a cast.
var aggregate = (TAggregate)constructor(aggregateId);
var history = eventStore.GetDomainEvents(aggregateId);
aggregate.LoadFromHistory(history);
return aggregate;
}
private Func<Guid, TAggregate> GetConstructorFunc<TAggregate>()
{
var parameter = Expression.Parameter(typeof(Guid), "aggregateId");
var constructor = typeof(TAggregate).GetConstructor(new[] { typeof(Guid) });
var lambda = Expression.Lambda<Func<Guid, TAggregate>>(Expression.New(constructor, parameter), parameter);
return lambda.Compile();
}
私はこれらの線に沿って何かを持っているしたいと思います:
private static readonly ConcurrentDictionary<Type, Func<Guid, SameTypeAsKey>> AggregateConstructors = new ConcurrentDictionary<Type, Func<Guid, SameTypeAsKey>>();
public TAggregate GetAggregate<TAggregate>(Guid aggregateId) where TAggregate : AggregateRoot
{
var constructor = AggregateConstructors.GetOrAdd(typeof(TAggregate), GetConstructorFunc<TAggregate>());
var aggregate = constructor(aggregateId);
var history = eventStore.GetDomainEvents(aggregateId);
aggregate.LoadFromHistory(history);
return aggregate;
}
private Func<Guid, TAggregate> GetConstructorFunc<TAggregate>()
{
var parameter = Expression.Parameter(typeof(Guid), "aggregateId");
var constructor = typeof(TAggregate).GetConstructor(new[] { typeof(Guid) });
var lambda = Expression.Lambda<Func<Guid, TAggregate>>(Expression.New(constructor, parameter), parameter);
return lambda.Compile();
}