4

SO でこの質問に答えている間、ジェネリック型の多くの実装をLifetimeScopeLifestyleSimpleInjector 内のインスタンスに登録するための最良の手法がわかりませんでした。

この形式の登録に推奨される方法は、次のようなものです。

container.RegisterManyForOpenGeneric(typeof(IRepository<>), 
    typeof(IRepository<>).Assembly);

LifetimeScopeLifestyleしかし、これは のインスタンスを渡すことを許可しません。

以下は私が思いついたものですが、具体的にではなく、一般的なインターフェイスをチェックしているため、十分な回復力がないことはわかっていますIRepository<>。誰でもこれを行う方法を教えてもらえますか?

public static void Configure(Container container)
{
    var lifetimeScope = new LifetimeScopeLifestyle();

    container.Register<IUnitOfWork, UnitOfWork>(lifetimeScope);

    //this query needs improvement
    var registrations =
        from type in typeof(IRepository<>).Assembly.GetExportedTypes()
        where typeof(IRepository).IsAssignableFrom(type)
            && type.IsClass
            && !type.IsAbstract
        from service in type.GetInterfaces()
        where service.IsGenericType
        select new { Service = service, Implementation = type };

    foreach (var registration in registrations)
    {
        container.Register(registration.Service, 
            registration.Implementation, lifetimeScope);
    }
}
4

1 に答える 1

3

TLDR:

container.RegisterManyForOpenGeneric(
    typeof(IRepository<>),
    lifetimeScope, 
    typeof(IRepository<>).Assembly);

まず、質問が間違っています。次のようになっているはずです。

var registrations =
    from type in
        typeof(IRepository<>).Assembly.GetExportedTypes()
    where !service.IsAbstract
    where !service.IsGenericTypeDefinition
    from @interface in type.GetInterfaces()
    where @interface.IsGenericType
    where @interface.GetGenericTypeDefinition() ==
        typeof(IRepository<>)
    select new { Service = @interface, Impl = type };

次に、フレームワークには、GetTypesToRegisterこれらの型をフェッチするメソッドが含まれていますが、デコレータの型は除外されています。

var repositoryTypes =
    OpenGenericBatchRegistrationExtensions.GetTypesToRegister(
        container, typeof(IRepository<>), 
        typeof(IRepository<>).Assembly);

var registrations =
    from type in repositoryTypes
    from @interface in type.GetInterfaces()
    where @interface.IsGenericType
    where @interface.GetGenericTypeDefinition() ==
        typeof(IRepository<>)
    select new { Service = @interface, Impl = type };

RegisterManyForOpenGenericしかし、コンテナには、次のように登録できるようにするコールバック デリゲートを受け取るメソッドのオーバーロードが含まれています。

container.RegisterManyForOpenGeneric(
    typeof(IRepository<>),
    (service, impls) =>
    {
        container.Register(service, impls.Single(),
            lifetimeScope);
    }, 
    typeof(IRepository<>).Assembly);

しかし、最も重要なことは、フレームワークには、RegisterManyForOpenGenericを受け取るオーバーロードが含まれていることLifetimeです。そのため、次のように登録を簡素化できます。

container.RegisterManyForOpenGeneric(
    typeof(IRepository<>),
    lifetimeScope, 
    typeof(IRepository<>).Assembly);
于 2013-04-18T17:38:58.817 に答える