3

私は次のものを持っています:

class Repository<T> : IRepository<T>
interface ISuperRepository<T> : IRepository<T>
class SuperRepository<T> : ISuperRepository<T>
interface ISuperType

キャッスル ウィンザー DIに条件付登録を希望するIRepository<T>場合TISuperType、提供しますISuperRepository<T>。それ以外の場合は、提供しますIRepository<T>.

たとえば、 の場合A : ISuperTypeResolve<IRepository<A>>を提供しSuperRepository<A>Resolve<IRepository<B>>を提供しますRepository<B>

どうすればそれを達成できますか?

4

2 に答える 2

2

Castle Windsorはそのようなことをサポートしていませんが、単純なヘルパー メソッドで実現できます。

public static void RegisterAccordingToISuperType<T>(this IWindsorContainer container)
{
    if (typeof (T).GetInterfaces().Contains(typeof (ISuperType)))
        container.Register(Component.For<IRepository<T>>()
                                    .ImplementedBy<SuperRepository<T>>());
    else
        container.Register(Component.For<IRepository<T>>()
                                    .ImplementedBy<Repository<T>>());
}

次に、登録:

container.RegisterAccordingToISuperType<SuperType>();
container.RegisterAccordingToISuperType<int>();

そして、解決は次のようになります。

var super = container.Resolve<IRepository<SuperType>>();
var intRepo = container.Resolve<IRepository<int>>();

別のオプションは、 の追加パラメータですComponent.For。次に、 Type から継承するすべての型 (たとえば) を取得して登録します。

private static void Register(...)
{
    foreach (var type in GetInheriteTypes())
    {          
        container.Register(Component.For(typeof(IRepository<>),type)
                                    .ImplementedBy(typeof(SuperRepository<>)));
    }
    container.Register(Component.For(typeof(IRepository<>))
                                .ImplementedBy(typeof(Repository<>)));
}

private static IEnumerable<Type> GetInheriteTypes()
{
    var listOfBs = (from domainAssembly in AppDomain.CurrentDomain.GetAssemblies()
                    from assemblyType in domainAssembly.GetTypes()
                    where assemblyType.GetInterfaces().Contains(typeof(ISuperType))
                    select assemblyType).ToArray();
    return listOfBs;
}
于 2015-07-19T16:13:58.110 に答える
-1

"where T: typename" 構文を使用して、ジェネリックが使用される型を制限できます。ここで、"typename" は、指定された型 'T' が継承 (または実装) しなければならない型を指します。あなたの場合、「where T: ISuperType」は特定のタイプに一致し、制限のないバージョンは残りすべてに一致するはずです。

参照。https://msdn.microsoft.com/en-us/library/bb384067.aspx

コンパイル時に実行できない場合は、実行時にいつでも実行できます (f.ex. 'is' を使用)。

于 2015-07-19T15:24:05.983 に答える