Unity - 基于泛型解决依赖

Unity - Resolve dependency based on generic type

我有一个名为 DocumentRepository<T> 的 class 带构造函数

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,字符串参数值

根据 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")));

编辑: 如果您担心易失性,我可以向您建议:

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

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);

我在这里找到了答案 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))