Unity -基于泛型类型解决依赖关系

本文关键字:解决 依赖 关系 泛型类型 Unity | 更新日期: 2023-09-27 18:02:55

我有一个名为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>))

一切顺利。

但是现在我想解析IDocumentCollectionNameCollectionNameFromClassNameCollectionNameFromString取决于泛型类型。

如果我有ClassA,我想要IDocumentCollectionName解析到CollectionNameFromClassName<ClassA>

如果我有ClassB,我想要IDocumentCollectionName解析到CollectionNameFromString与字符串参数值

Unity -基于泛型类型解决依赖关系

我在这里找到了答案非泛型接口的统一注册泛型类型

结束代码看起来像

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

根据这个答案,这可能行得通:

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