Как. NET Core DI определяет неопределенный параметр generi c, такой как ILogger? - PullRequest
0 голосов
/ 17 апреля 2020

(Этот вопрос по ILogger разрешен в этом вопросе . Мой вопрос спрашивает, как это выполняет система DI)

Мне было любопытно, как. NET Core ILogger<MyClass> может быть разрешено для любого типа MyClass. Я проверил исходный код и нашел этот:

services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>)));

Так что я понимаю, что когда мне нужно ILogger<MyClass>, DI автоматически создаст Logger<MyClass>. У меня вопрос от Reflection, как это происходит? Я сделал этот код для исследования:

        var t1 = typeof(IList<>);
        Console.WriteLine(t1.FullName); // System.Collections.Generic.IList`1
        Console.WriteLine(t1.IsGenericType); // True
        Console.WriteLine(t1.GetGenericArguments()[0].Name); // T
        Console.WriteLine(t1.GetGenericArguments()[0].FullName); // null

        var t2 = typeof(IList<int>);
        Console.WriteLine(t2.FullName); // System.Collections.Generic.IList`1...
        Console.WriteLine(t2.IsGenericType); // True
        Console.WriteLine(t2.GetGenericArguments()[0].Name); // Int32
        Console.WriteLine(t2.GetGenericArguments()[0].FullName); // System.Int32

Как ни странно, t1 все еще имеет действительный результат GetGenericArguments() с типом T (и ноль FullName). Это как реализация DI проверяет, является ли тип ввода Something<>?

1 Ответ

0 голосов
/ 17 апреля 2020

Я нашел недвижимость ContainsGenericParameters. Это всегда должно быть true для типа, подобного typeof(IList<>) и false в противном случае.

Получает значение, указывающее, имеет ли текущий объект Type параметры типа, которые не были заменены спецификацией c types.

Я могу представить, что реализация DI похожа на это:

        var abstraction = typeof(IList<>);
        var impl = typeof(List<>);

        var genericServices = new Dictionary<Type, Type>();
        if (abstraction.ContainsGenericParameters)
        {
            genericServices.Add(abstraction.GetGenericTypeDefinition(), impl);

            // Other services
        }

Запрос на обслуживание:

        var request = typeof(IList<int>);
        if (request.IsGenericType)
        {
            var requestGenType = request.GetGenericTypeDefinition();

            foreach (var genericService in genericServices)
            {
                if (requestGenType == genericService.Key)
                {
                    var implType = genericService.Value;

                    // Construct the dependency base on the information of implType
                }
            }

            // Not found service
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...