如何获取所有ILogger<whatever>类型?

问题描述 投票:0回答:1

当我谷歌时,我正在寻找有关如何获取泛型类的所有派生类型的答案。但我真正想要的只是通用类的所有变体。

问题是我们在更高的环境中记录了太多信息。我们使用Serilog,我想使用

MinimumLevel.Overide()
方法来根据环境控制日志记录。

为了做到这一点,我需要指定日志记录源。因为应用程序中有很多类型,并且肯定会添加更多类型,所以我想使用反射来查找

ILogger<whatever>
的每个类。

c# reflection serilog
1个回答
0
投票

这是一个非常有趣的问题!首先,您想要反映的程序集静态地知道您的所有

ILogger<whatever>
并包含在其元数据中。你不知道确切的类型,你必须遍历所有的程序集类型,包括嵌套类型。最有可能的是,您希望从加载的所有程序集中检索类。

让我们从我们需要使用的库类型开始:

using Type = System.Type;
using TypeList = System.Collections.Generic.List<System.Type>;
using Assembly = System.Reflection.Assembly;
using AppDomain = System.AppDomain;

现在,为了便于说明,让我们在某处定义

ILogger
和一些实现类:

internal interface ILogger<TYPE> {
    //...
}
internal class StringLogger : ILogger<string> {
    //...
}
internal class TimeLogger : ILogger<System.DateTime> {
    //...
}
internal class AssemblyLogger : ILogger<System.Reflection.Assembly> {
    //...
}

在您的实际代码中,您将需要使用真正的

ILogger
通用接口,但您将没有有关实现类的信息。让我们找回它们:

static class LoggerClassifier {

    static void GetLoggerClasses(Assembly assembly, TypeList collection) {
        Type loggerType = typeof(ILogger<>);
        Type[] assemblyTypes = assembly.GetTypes();
        foreach (var type in assemblyTypes) {
            Type[] interfaces = type.GetInterfaces();
            foreach (var interfaceInstance in interfaces) {
                if (!interfaceInstance.IsGenericType) continue;
                if (loggerType == interfaceInstance.GetGenericTypeDefinition())
                    collection.Add(type);
            } //loop
        } //loop
    } //GetLoggerClasses

    internal static Type[] GetLoggerClasses() {
        TypeList collection = new();
        Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
        foreach (var assembly in assemblies)
            GetLoggerClasses(assembly, collection);
        return collection.ToArray();
    } //GetLoggerClasses

    //...

} //class LoggerClassifier

让我们测试一下:

Type[] loggerTypes = LoggerClassifier.GetLoggerClasses();

检查

loggerTypes
,您会发现在当前应用程序域中找到了两个类:
StringLogger
TimeLogger
AssemblyLogger
。不管怎样,无论您应用到的通用参数
ILogger<>

就是这样!

谢谢。
—SA

© www.soinside.com 2019 - 2024. All rights reserved.