Загрузка сборок и представлений во время выполнения с net core 3 MVC - PullRequest
0 голосов
/ 18 марта 2020

как дела? Я пришел к вам за помощью.

Я говорю вам, у меня есть MVC веб-приложение, разработанное в asp net core 3.

У меня есть базовое MVC веб-приложение, которое содержит области и обрабатывает основные c функциональные возможности приложения для управления пользователями, права доступа и т. Д. c.

Теперь я хочу добавить новую область для определенной c функциональности, которая в этом случае будет управлять клиентом. Чего я не хочу, так это добавить область непосредственно в базовый проект.

Я хочу динамически загружать dll-файлы и представления, чтобы разделить функциональные возможности и, если один из них выйдет из строя, другой продолжит работать.

Реализация функциональности для загрузки DLL, это работает, потому что я тестировал его с веб-интерфейсом.

Но я не могу найти способ загрузить виды областей, это я сделал с помощью MVC 5 Net Framework, попробуйте передать функциональность и, очевидно, классы не совпадают. Вы могли бы помочь мне с этим.

Заранее большое спасибо.

Ниже кода:

PluginExtensions.cs

public static class PluginExtensions
{

    public static IMvcBuilder AddExtensions(this IMvcBuilder mvc)
    {
        var serviceProvider = mvc.Services.BuildServiceProvider();
        var configuration = serviceProvider.GetService<IConfiguration>();
        var hostingEnvironment = serviceProvider.GetService<IWebHostEnvironment>();
        var logger = serviceProvider.GetService<ILoggerFactory>().CreateLogger<Startup>();
        List<string> extensionDirectories = EnumerateExtensionDirectories(serviceProvider).ToList();
        List<string> searchPatternList = new List<string>
        {
            "*Extension.Mvc*.dll"
        };
        mvc.ConfigureApplicationPartManager(apm =>
        {
            List<string> extensionAssemblies = new List<string>();
            foreach (var extensionDirectory in extensionDirectories)
            {
                for (int i = 0; i < searchPatternList.Count; i++)
                {
                    List<string> tempList = EnumerateExtensionAssemblies(extensionDirectory, searchPatternList[i]).ToList();
                    if (tempList != null && tempList.Count > 0)
                        extensionAssemblies.AddRange(tempList);
                }//for(int i=0;i< searchPatternList.Count; i++)
            }//foreach (var extensionDirectory in extensionDirectories)
            foreach (var extensionAssembly in extensionAssemblies)
            {
                if (TryLoadExtensionAssembly(serviceProvider, extensionAssembly, out var assembly))
                {
                    //logger.Log(AbortAction.Layer.Infrastructure().Meta(new { extensionAssembly = new { extensionAssembly.FullName } }));
                    apm.ApplicationParts.Add(new AssemblyPart(assembly));
                }// if (TryLoadExtensionAssembly(serviceProvider, extensionAssembly, out var assembly))
            }// foreach (var extensionAssembly in extensionAssemblies)


        });

        if (hostingEnvironment.IsProduction() || hostingEnvironment.IsDevelopment())
        {
            ConfigureAssemblyResolve(serviceProvider);
        }
        return mvc;
    }

    private static IEnumerable<string> EnumerateExtensionAssemblies(IServiceProvider serviceProvider)
    {
        var configuration = serviceProvider.GetService<IConfiguration>();
        var hostingEnvironment = serviceProvider.GetService<IWebHostEnvironment>();

        var extRootPath = Path.Combine(hostingEnvironment.ContentRootPath, configuration["Extensibility:Ext"]);
        if (!Directory.Exists(extRootPath)) return new List<string>();
        return Directory.EnumerateFiles(extRootPath, "*Extension.Mvc*.dll");
    }
    private static IEnumerable<string> EnumerateExtensionAssemblies(string assembliesDirectory, string searchPattern)
    {
        if (!Directory.Exists(assembliesDirectory)) return new List<string>();
        return Directory.EnumerateFiles(assembliesDirectory, searchPattern);
    }
    private static IEnumerable<string> EnumerateExtensionDirectories(IServiceProvider serviceProvider)
    {
        var configuration = serviceProvider.GetService<IConfiguration>();
        var hostingEnvironment = serviceProvider.GetService<IWebHostEnvironment>();

        var extRootPath = Path.Combine(hostingEnvironment.ContentRootPath, configuration["Extensibility:Ext"]);
        if (!Directory.Exists(extRootPath)) return new List<string>();
        return Directory.EnumerateDirectories(extRootPath);
    }
    private static bool TryLoadExtensionAssembly(IServiceProvider serviceProvider, string extensionAssembly, out Assembly assembly)
    {

        //extensionAssembly
        try
        {
            if (File.Exists(extensionAssembly))
            {
                assembly = Assembly.LoadFile(extensionAssembly);
                return true;
            }
        }
        catch (Exception ex)
        {
            // logger.Log(Abstraction.Layer.Infrastructure().Routine(nameof(TryLoadExtensionAssembly)).Faulted(), ex);
        }

        assembly = default;
        return false;
    }
    private static void ConfigureAssemblyResolve(IServiceProvider serviceProvider)
    {
        var configuration = serviceProvider.GetService<IConfiguration>();
        var hostingEnvironment = serviceProvider.GetService<IWebHostEnvironment>();
        var logger = serviceProvider.GetService<ILoggerFactory>().CreateLogger<Startup>();
        List<string> extensionDirectories = EnumerateExtensionDirectories(serviceProvider).ToList();
        List<string> extensionAssemblies = new List<string>();
        List<string> searchPatternList = new List<string>
        {
            "*Extension.Entities*.dll",
            "*Extension.Libs*.dll",
            "*Extension.Data*.dll",
            "*Extension.Application*.dll",
            "*Extension.UtilsConnectors*.dll"
        };
        foreach (var extensionDirectory in extensionDirectories)
        {
            for (int i = 0; i < searchPatternList.Count; i++)
            {
                List<string> assembliesReferenceList = EnumerateExtensionAssemblies(extensionDirectory, searchPatternList[i]).ToList();
                if (assembliesReferenceList != null && assembliesReferenceList.Count > 0)
                    foreach (var assemblyReference in assembliesReferenceList)
                    {
                        AppDomain.CurrentDomain.AssemblyResolve += (sender, e) =>
                        {
                            return
                                File.Exists(assemblyReference)
                                    ? Assembly.LoadFile(assemblyReference)
                                    : null;
                        };// AppDomain.CurrentDomain.AssemblyResolve += (sender, e) =>
                    }//foreach (var assemblyReference in assembliesReferenceList)
            }// for (int i = 0; i < searchPatternList.Count; i++)
        }//foreach (var extensionDirectory in extensionDirectories)
    }
}
public static class HostingEnvironmentExtensions
{
    public static bool IsDevelopmentExt(this IWebHostEnvironment hostingEnvironment)
    {
        return hostingEnvironment.IsEnvironment("DevelopmentExt");
    }
}

Startup.cs

 public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddMvc(options =>
        {
            options.Filters.Add(new SessionExpireAttribute());
        }).AddExtensions();
        ...
    }

Как вы можете видеть, я загружаю файлы DLL, это работает.

Позже я копирую файлы (dll и views (html)) в папку областей моего базового проекта

enter image description here

DLL в моем районе

enter image description here

Наконец, просмотр моего района

enter image description here

Результат

enter image description here

Наконец в файле startup.cs расширения типа проекта.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
       ... 
       app.UseEndpoints(endpoints =>
        {
            endpoints.MapAreaControllerRoute(
           name: "AreaMyArea",
           areaName: "MyArea",
           pattern: "MyArea/{controller=MYHome}/{action=Index}/{id?}");
            endpoints.MapControllerRoute(
              name: "defaultMA",
              pattern: "{controller=MyExtHome}/{action=Index}/{id?}");

        });
    }

Извините за обширность этой информации. Вы можете помочь мне?. Я старался быть максимально ясным. Большое спасибо и хорошего дня.

...