Добавлять новые местоположения FileServer после запуска (редактировать промежуточное ПО после запуска)

Мое веб-приложение должно позволять пользователю-администратору добавлять и удалять обслуживаемые папки из приложения .net core 2. Я нашел способ предоставить список обслуживаемых папок, но не могу найти способ их динамического добавления или удаления после настройки приложения.

Как повторно запустить функцию настройки из приложения? В качестве альтернативы, как добавить или удалить UseFileServer() конфигурации в уже работающей службе?

public class Startup
{
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        app.UseDeveloperExceptionPage();
        app.UseMvc();

        //get these dynamically from the database
        var locations = new Dictionary<string, string>{
            {@"C:\folder1", "/folder1"},
            {@"D:\folder2", "/folder2"}
        };
        foreach (var kvp in locations)
        {
            app.UseFileServer(new FileServerOptions()
            {
                FileProvider = new PhysicalFileProvider(
                    kvp.Key
                ),
                RequestPath = new PathString(kvp.Value),
                EnableDirectoryBrowsing = true
            });
        }
    }
}

Я использую .net core 2.0.0-preview2-final.


person TwitchBronBron    schedule 16.08.2017    source источник


Ответы (1)


Возможно, вы захотите динамически внедрить промежуточное ПО FileServer на основе ваших настроек.

На Github Криса Росса от Microsoft есть пример проекта: https://github.com/Tratcher/MiddlewareInjector/tree/master/MiddlewareInjector

Вам нужно будет добавить в свой проект классы MiddlewareInjectorOptions, MiddlewareInjectorMiddleware и MiddlewareInjectorExtensions из вышеупомянутого репозитория.

Затем в своем классе Startup зарегистрируйте MiddlewareInjectorOptions как синглтон (чтобы он был доступен во всем приложении) и используйте MiddlewareInjector:

public class Startup
{
    public void ConfigureServices(IServiceCollection serviceCollection)
    {
        serviceCollection.AddSingleton<MiddlewareInjectorOptions>();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseDeveloperExceptionPage();

        var injectorOptions = app.ApplicationServices.GetService<MiddlewareInjectorOptions>();
        app.UseMiddlewareInjector(injectorOptions);
        app.UseWelcomePage();
    }
}

Затем внедрите MiddlewareInjectorOptions в любое место и динамически настройте промежуточное ПО, например:

public class FileServerConfigurator
{
    private readonly MiddlewareInjectorOptions middlewareInjectorOptions;

    public FileServerConfigurator(MiddlewareInjectorOptions middlewareInjectorOptions)
    {
        this.middlewareInjectorOptions = middlewareInjectorOptions;
    }

    public void SetPath(string requestPath, string physicalPath)
    {
        var fileProvider = new PhysicalFileProvider(physicalPath);

        middlewareInjectorOptions.InjectMiddleware(app =>
        {
            app.UseFileServer(new FileServerOptions
            {
                RequestPath = requestPath,
                FileProvider = fileProvider,
                EnableDirectoryBrowsing = true
            });
        });
    }
}

Обратите внимание, что этот MiddlewareInjector может внедрить только одно промежуточное ПО, поэтому ваш код должен вызывать UseFileServer() для каждого пути, который вы хотите обслуживать.

Я создал Gist с необходимым кодом: https://gist.github.com/michaldudak/4eb6b0b26405543cff4c4f01a51ea869

person Michał Dudak    schedule 22.08.2017
comment
Это не решает мою проблему. Мне нужно зарегистрировать новые местоположения UseFileServer ПОСЛЕ завершения запуска. Я проверил это, и как только приложение запущено, любые новые вызовы app.UseFileServer просто ничего не делают. - person TwitchBronBron; 22.08.2017
comment
Тогда мое решение должно работать. Поскольку у вас есть singleton MiddlewareInjectorOptions, вы можете использовать его, когда захотите (просто получите его из сервисного контейнера). Я проверил это на себе некоторое время назад, и, похоже, он работает нормально. - person Michał Dudak; 22.08.2017
comment
Пожалуйста, взгляните на Gist, который я только что добавил. Во-первых, функциональность файлового сервера отсутствует. Только при переходе по URL-адресу /enable-file-server вы сможете получить доступ к содержимому дисков C и D, перейдя по URL-адресам /c и /d соответственно. - person Michał Dudak; 22.08.2017
comment
Должно быть, я сделал что-то не так, когда пробовал в первый раз. Этот Gist тоже очень помог. Теперь это работает отлично. Спасибо! И респект за отличное решение! - person TwitchBronBron; 22.08.2017
comment
Я рад, что смог помочь :) Кстати, не могли бы вы изменить заголовок на что-то вроде «Как модифицировать промежуточное ПО после запуска»? - Думаю, так его будет легче обнаружить, и он может помочь и другим. - person Michał Dudak; 22.08.2017
comment
@MichałDudak Я пытаюсь сделать что-то подобное, но есть ли способ удалить промежуточное ПО? Например, я хотел бы удалить внешнего поставщика проверки подлинности, который был настроен в Startup.cs. - person Evan; 13.10.2017
comment
@Evan, вы можете обернуть промежуточное ПО аутентификации в метод MapWhen (см. docs.microsoft.com/en-us/aspnet/core/fundamentals/), который будет проверять, нужно ли запускать промежуточное ПО. Таким образом, вы не удалите, а отключите нежелательное промежуточное ПО. - person Michał Dudak; 16.10.2017