IHandleEvent<T>
あなたはout
修飾子を追加することによって、それを追加することができます共変ではありませんので、あなたはIHandleEvent<IEvent>
にIHandleEvent<EventThree>
をキャストすることはできません。
public interface IHandleEvent<out TEvent>
where TEvent : IEvent
{ }
残念ながらAutofacは共変タイプだけ反変タイプをサポートしていません。 ところで、カスタムのIRegistrationSource
実装を作成して、要求された動作をさせることができます。このような何か:
public class CovariantHandleEventRegistrationSource : IRegistrationSource
{
public bool IsAdapterForIndividualComponents
{
get
{
return false;
}
}
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service,
Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
IServiceWithType typedService = service as IServiceWithType;
if (typedService == null)
{
yield break;
}
if (typedService.ServiceType.IsGenericType && typedService.ServiceType.GetGenericTypeDefinition() == typeof(IHandleEvent<>))
{
IEnumerable<IComponentRegistration> eventRegistrations = registrationAccessor(new TypedService(typeof(IEvent)));
foreach (IComponentRegistration eventRegistration in eventRegistrations)
{
Type handleEventType = typeof(IHandleEvent<>).MakeGenericType(eventRegistration.Activator.LimitType);
IComponentRegistration handleEventRegistration = RegistrationBuilder.ForDelegate((c, p) => c.Resolve(handleEventType, p))
.As(service)
.CreateRegistration();
yield return handleEventRegistration;
}
}
}
}
このIRegistrationSource
では、あなたがこれを持つことができます。
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<EventOne>().As<IEvent>();
builder.RegisterType<EventTwo>().As<IEvent>();
builder.RegisterType<EventThree>().As<IEvent>();
builder.RegisterAssemblyTypes(typeof(Program).Assembly)
.AsClosedTypesOf(typeof(IHandleEvent<>));
builder.RegisterSource(new CovariantHandleEventRegistrationSource());
IContainer container = builder.Build();
var x = container.Resolve<IEnumerable<IHandleEvent<IEvent>>>();
'のIEnumerable>'丁度1コンクリートの型に解決する必要があるでしょう。動的にビルドできるタイプ(Builderパターンを参照)があれば、それを定義し、 'IEnumerable >'の登録としてAutoFacで登録することができます。また、DIコンテナをビルドするために追加の情報を取得する必要がある場合は、そのタイプのDIコンテナを挿入することもできます。つまり、IEnumerable >インスタンスを解決するには、ビルダーまたは工場パターンが必要です。 –
Igor
ありがとうございます。私はデリゲート工場のautofac docを見ました。この場合、コンテナは工場に注入され、さまざまな種類のIHandleEvent <>が解決されます。 – Suedeuno
'IHandleEvent'を 'IHandleEvent 'に書き換えようとしてください。 Autofacは分散のためのサポートをいくつか持っていて、そうするときに自動的に登録を受け取るかもしれません。しかし、私はいつもAutofacが共分散または反共をサポートしているかどうか忘れているので、試してみる必要があります。 –
Steven