ASP. NET Основная реализация IStartupFilter - PullRequest
0 голосов
/ 06 апреля 2020

Я сейчас изучаю ASP. NET Ядро и его возможности. Одной из его особенностей является интерфейс IStartupFilter для использования в методе Startup для регистрации промежуточного программного обеспечения. У меня есть этот пример реализации метода Configure (весь класс, реализующий этот интерфейс не показан), который внедряет часть пользовательского промежуточного программного обеспечения с именем PrincipalInjectionMiddleware:

            public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
            {
                return builder =>
                {
                    builder.UseMiddleware<PrincipalInjectionMiddleware>();
                    next(builder);
                };
            }

Я понимаю, Action<IApplicationBuilder> инкапсулирует метод, который не возвращает значение. Тогда почему приведенный выше оператор return принимается как допустимый синтаксис, а не это (переменная _serviceProvider исходит из конструктора, не показанного здесь):

            public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
            {
                IApplicationBuilder builder = new ApplicationBuilder(_serviceProvider);
                    builder.UseMiddleware<PrincipalInjectionMiddleware>();

                next(builder);
            }

Приведенный выше код выдает ошибку, которую возвращают не все пути кода ценность. Код ниже также не работает, так как невозможно преобразовать void в Action<IApplicationBuilder>:

            public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
            {
                IApplicationBuilder builder = new ApplicationBuilder(_serviceProvider);
                    builder.UseMiddleware<PrincipalInjectionMiddleware>();

                return next(builder);
            }

Я считаю, что Action<IApplicationBuilder> похож на void, так как он не возвращает значение , Это «особый» случай? Можно ли переписать этот метод без лямбда-выражения? Если да, то как?

Ответы [ 2 ]

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

Причина, по которой это происходит, заключается в том, что метод Configure возвращает действие, которое просто означает МЕТОД, который принимает IApplicationBuilder в качестве параметра и возвращает void.

Действие означает метод, который возвращает void.

Fun c означает метод, который возвращает что-либо.

Action и Fun c являются оберткой для «делегатов», которые являются просто «указателями» на методы.

Делегаты - это способ сохранения метода в переменной. Создать ссылку на метод, который можно передавать и вызывать в других местах.

Другими словами, они являются синтаксическим сахаром (более или менее) для использования делегатов для хранения ссылок на методы.

Вы можете, например, сделать это:

    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
    {
        var builder = new ApplicationBuilder(_serviceProvider);
        builder.UseMiddleware<PrincipalInjectionMiddleware>();

        next(builder);

        return next;//notice I am returning the ACTION not the return of the action
    }

Позвольте мне привести более четкий пример:

    public Action<IApplicationBuilder> Configure()
    {
        BuildAction(new ApplicationBuilder(_serviceProvider));//call the method

        return BuildAction;//return the actual method name... NOT a method call
    }

    //this method is being returned as a reference in the Configure method...
    private void BuildAction(IApplicationBuilder builder) 
    {
        builder.UseMiddleware<PrincipalInjectionMiddleware>();        
    }

Смотрите в предыдущем примере, я возвращаю АКТУАЛЬНЫЙ метод ... НЕ вызов метода.

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

РЕДАКТИРОВАТЬ: Вы должны использовать указатель функции некоторого вида, потому что это то, что Действие - инкапсуляция указателя функции.

Тип возвращаемого значения для Configure не void, это Action<IApplicationBuilder>, и поэтому метод должен возвращать что-то такого типа. В ваших примерах вы не возвращаете такое Действие - вы пытаетесь выполнить код напрямую.

Действие «подобно» void в том смысле, что Действие возвращает void, но оно не совпадает с недействительным. В этом случае Action - это некоторый код, который может быть выполнен, но пока не выполнен. Какой-то другой код в какой-то другой области действия решит, хочет ли он выполнить это действие.

РЕДАКТИРОВАТЬ: По комментариям к этому ответу: Вы можете использовать лямбда-выражение или обернуть код в фактическую функцию:

    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
    {
        return MyFunction;
    }

    public void MyFunction(IApplicationBuilder next)
    {
        // insert code here
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...