Unity - 根据泛型

时间:2016-08-18 16:15:57

标签: c# generics inversion-of-control unity-container azure-cosmosdb

我有一个名为DocumentRepository<T>的班级 与构造函数

DocumentDbRepository(IDocumentCollectionName collectionName)

IDocumentCollectionName 可以是

CollectionNameFromClassName<T>

CollectionNameFromString

我正在通过

来解决这个问题
container.RegisterType(typeof(IDocumentDbRepository<ClassA>), typeof(DocumentDbRepository<ClassA>))

container.RegisterType(typeof(IDocumentDbRepository<ClassB>), typeof(DocumentDbRepository<ClassB>))

到目前为止一切顺利。

但现在我想将 IDocumentCollectionName 解析为CollectionNameFromClassNameCollectionNameFromString,具体取决于通用类型。

因此,如果我有ClassA,我希望 IDocumentCollectionName 解析为CollectionNameFromClassName<ClassA>

如果我有ClassB,我希望 IDocumentCollectionName 使用字符串参数值解析为CollectionNameFromString

2 个答案:

答案 0 :(得分:0)

根据this answer,这可能有效:

container.RegisterType<IDocumentCollectionName, CollectionNameFromClassName<ClassA>>("ForClassA");
container.RegisterType<IDocumentCollectionName, CollectionNameFromString>("ForClassB");

container.RegisterType<IDocumentDbRepository<ClassA>, DocumentDbRepository<ClassA>>(new InjectionConstructor(new ResolvedParameter<IDocumentCollectionName>("ForClassA")));
container.RegisterType<IDocumentDbRepository<ClassB>, DocumentDbRepository<ClassB>>(new InjectionConstructor(new ResolvedParameter<IDocumentCollectionName>("ForClassB")));

编辑:如果您关注的是lisibility,我可以向您求婚,

首先,您创建一个函数来执行类似工厂的操作:

void RegisterDocumentDbRepository<TRepository, TCollection>(ContainerType container)
{
    container.RegisterType<IDocumentCollectionName, TCollection>(typeof(TRepository).Name);
    var constructor = new InjectionConstructor(new ResolvedParameter<IDocumentCollectionName>(typeof(TRepository).Name));
    container.RegisterType<IDocumentDbRepository<TRepository>, DocumentDbRepository<TRepository>>(constructor);
}

然后,你注册你的类型:

RegisterDocumentDbRepository<ClassA, CollectionNameFromClassName<ClassA>>(container);
RegisterDocumentDbRepository<ClassB, CollectionNameFromString>(container);

答案 1 :(得分:0)

我在这里找到了答案 Unity register generic type for non generic interface

结束代码看起来像

container.RegisterInstance<Func<Type, IDocumentCollectionName>>(type =>
{
    if (type == typeof(ClassA))
        return
            (IDocumentCollectionName)
                container.Resolve(typeof(CollectionNameFromClassName<>).MakeGenericType(type));
    else
        return (IDocumentCollectionName)
            container.Resolve(typeof(CollectionNameFromString));

});

当然这意味着我必须改变我的

DocumentDbRepository(IDocumentCollectionName collectionName)

Func<Type, IDocumentCollectionName> collectionName

并将其解析为

collectionName(typeof(T))