插件中的ASP .NET Core MVC 2.1 mvc视图 [英] ASP .NET Core MVC 2.1 mvc Views in plugin

查看:89
本文介绍了插件中的ASP .NET Core MVC 2.1 mvc视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个困扰我几天的问题.

I have a problem that has tormented me for several days.

就像我在ASP .NET Core MVC中的插件中所做的那样,通过插件为我带来视图

As I do in a plugin in ASP .NET Core MVC to bring me views with the plugin

我有这种情况

解决方案:EVS

  • 控制器
    • ...
    • Controllers
      • ...
      • ...
      • 此文件夹包含一个插件dll

      文件IPlugin.cs

      file IPlugin.cs

      ...
      using McMaster.NETCore.Plugins;
      
      namespace EVS
      {
          public interface IPlugin
          {
              string Name { get; }
              void Do();
              void BootReg();
              void BootExecute();
              void PluginConfigure(IApplicationBuilder app, IHostingEnvironment env);
              void PluginConfigureServices(IServiceCollection services);
          }
      
          public class PluginsManager
          {
              public List<PluginLoader> PluginLoaders;
      
              public Dictionary<string, IPlugin> Plugins;
              public Dictionary<string, Assembly> Views;
              public List<String> dllFileNames;
      
              public PluginsManager()
              {
                  PluginLoaders = new List<PluginLoader>();
                  Plugins = new Dictionary<string, IPlugin>();
                  dllFileNames = new List<string>();
                  string PloginDirectory= Path.Combine(AppContext.BaseDirectory, "Plugins");
                  if (Directory.Exists(PloginDirectory))
                      dllFileNames.AddRange(Directory.GetFiles(PloginDirectory+"\\", "*.dll"));
      
                  foreach (string dllFile in dllFileNames)
                  {
                      if (!dllFile.Contains(".Views.dll"))
                      {
                          var loader = PluginLoader.CreateFromAssemblyFile(dllFile,sharedTypes: new[] { typeof(IPlugin) });
                          PluginLoaders.Add(loader);               
                      }
                      else
                      {
                          // 
      
                          //
                      }   
                  }
                  foreach (var loader in PluginLoaders)
                  {
                      foreach (IPlugin plugin in loader.LoadDefaultAssembly().GetTypes().Where(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsAbstract).Select((x)=> (IPlugin)Activator.CreateInstance(x)))
                          if (!Plugins.ContainsKey(plugin.Name))
                              Plugins.Add(plugin.Name, plugin);
                  }
              }
          }
      }
      

      文件Program.cs

      file Program.cs

      namespace EVS
      {
          public class Program
          {
              public static void Main(string[] args)
              {
                  foreach (IPlugin plugin in Global.Static.PluginsManager.Plugins.Select((x) => x.Value))
                      plugin.BootReg();           
      
                  CreateWebHostBuilder(args).Build().Run();
              }
      
              public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                  WebHost.CreateDefaultBuilder(args)
                      .UseStartup<Startup>();
          }
      }
      

      文件Startup.cs

      file Startup.cs

      namespace EVS
      {
          public class Startup
          {
              public Startup(IConfiguration configuration)
              {
                  Configuration = configuration;
              }
      
              public IConfiguration Configuration { get; }
      
              public void ConfigureServices(IServiceCollection services)
              {
                  services.Configure<CookiePolicyOptions>(options =>
                  {
                      options.CheckConsentNeeded = context => true;
                      options.MinimumSameSitePolicy = SameSiteMode.None;
                  });
      
      
                  services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
      
                  foreach (IPlugin plugin in Global.Static.PluginsManager.Plugins.Select((x) => x.Value))
                  {
                      plugin.PluginConfigureServices(services);
                  }                
              }
      
              public void Configure(IApplicationBuilder app, IHostingEnvironment env)
              {
                  if (env.IsDevelopment())
                  {
                      app.UseDeveloperExceptionPage();
                  }
                  else
                  {
                      app.UseExceptionHandler("/Home/Error");
                  }
      
                  app.UseStaticFiles();
                  app.UseCookiePolicy();
      
                  foreach (IPlugin plugin in Global.Static.PluginsManager.Plugins.Select((x) => x.Value))
                  {
                      plugin.PluginConfigure(app,env);
                  }
      
                  app.UseMvc(routes =>
                  {
                      routes.MapRoute(
                      name: "default",
                      template: "{controller=Home}/{action=Index}/{id?}");
                  });
              }
          }
      }
      

      现在让我们以插件为例

      solution:EVS.TestPlugin

      solution:EVS.TestPlugin

      • 控制器
        • TestPluginController.cs
        • Controllers
          • TestPluginController.cs
          • test.cshtml

          文件:TestPlugin.cs

          file: TestPlugin.cs

          namespace EVS.TestPlugin
          {
              internal class TestPlugin : IPlugin
              {
                  public string Name
                  {
                      get
                      {
                          return "TestPlugin";
                      }
                  }
          
                  public void BootReg()
                  {
                      ...
                  }
          
                  public void BootExecute()
                  {
                      ...
                  }
          
                  public void Do()
                  {
          
                  }
          
          
                  public void PluginConfigure(IApplicationBuilder app, IHostingEnvironment env)
                  {
                      app.UseMvc(routes =>
                      {
                          routes.MapRoute("TestPlugin", "TestPlugin/", new { controller = "TestPlugin", action = "index" });
                          routes.MapRoute("TestPlugint1", "TestPlugin/t1", new { controller = "TestPlugin", action = "t1" });
                      });
                  }
          
                  public void PluginConfigureServices(IServiceCollection services)
                  {
          
                      services.AddMvc().AddApplicationPart(typeof(TestPluginController).GetTypeInfo().Assembly).AddControllersAsServices();
                  }
          
              }
          }
          

          文件:Controllers/TestPluginController.cs

          file: Controllers/TestPluginController.cs

          namespace EVS.TestPlugin.Controllers
          {
              public class TestPluginController : Controller
              {
                  public IActionResult Index()
                  {
                      return Content("<h1>TestPluginController</h1>");
                  }
          
                  public IActionResult t1()
                  {
                      return View("test");
                  }
              }
          }
          

          文件:Views/test.cshtml

          file : Views/test.cshtml

          @{
              Layout = null;
          }
          
          `.cshtml` test view
          

          解决方案中不包含插件,但是会根据它们是否庄重地位于文件夹中来动态加载它们.

          Plugins are not included in the solution, but they are loaded dynamically depending whether they are in a folder solemnly for them.

          问题: 我可以相应地添加控制器为 (EVS.TestPlugin.PluginConfigureServices (...))MapRoute (EVS.TestPlugin.PluginConfigure (...)) 但是,如何添加视图的上下文呢? 因此它将打开: ~/PluginName/Views/ViewName.cshatml

          The problem: I can accordingly add controllers as (EVS.TestPlugin.PluginConfigureServices (...)) and MapRoute (EVS.TestPlugin.PluginConfigure (...)) However, how could I also add the context of the views? Therefore it would be on: ~/PluginName/Views/ViewName.cshatml

          编辑

          我找到了这个(链接),但这并不是我真正需要的.它部分解决了该问题,因为它仅在视图被编译时才起作用.

          I found this (link), but it's not really what I need. It partially solve the problem, because it only work if the view are compiled.

          编辑2

          我立即解决了它,将视图引用添加到插件csproj上,如下所示:

          Momentarily I solved it adding the views reference on to the plugins csproj, as follows:

          <ItemGroup>
              <EmbeddedResource Include="Views\**\*.cshtml"/>
              <Content Remove="Views\**\*.cshtml" />
          </ItemGroup>
          <PropertyGroup>
              <RazorCompileOnBuild>false</RazorCompileOnBuild>
          </PropertyGroup>
          

          在源项目上:

          // p is a Instance of plugin
          foreach(IPlugin p in Plugins.Select((x) => x.Value))
              services.Configure<RazorViewEngineOptions>(options =>
              {
                  options.FileProviders.Add(
                              new EmbeddedFileProvider(p.GetType().GetTypeInfo().Assembly));
              });
          

          这不能解决我的问题,因为.cshtml文件在插件文件中清晰可见,我需要的是能够从程序集pluginname.views.dll或其他方式添加视图,这一点很重要视图已编译

          This does not solve my problem because the .cshtml files come in clear in the plugin file, what I need is to be able to add the views from the assembly pluginname.views.dll or in some other way, the important that the views are compiled

          编辑3

          好消息,我使用ILSpy解析了PluginName.Views.dll文件,发现它实现了RazorPage<object>

          Good news, using ILSpy I parsed a PluginName.Views.dll file and I discovered that it implements RazorPage<object>

          使用以下代码,我验证了我可以初始化所有cono RazorPage<object>的缓存,这使我可以拥有创建视图的对象的实例

          With the following code I verified that I could initialize all the caches that cono RazorPage<object> which allows me to have the instances of the objects that create the view

          foreach (string dllview in Views.Select((x) => x.Key))
          {
              PluginLoader loader = PluginLoader.CreateFromAssemblyFile(dllview, sharedTypes: new[] { typeof(RazorPage<object>) });
              foreach (RazorPage<object> RazorP in loader.LoadDefaultAssembly().GetTypes().Where(t => typeof(RazorPage<object>).IsAssignableFrom(t)).Select((x) => (RazorPage<object>)Activator.CreateInstance(x)))
              {
                  // i need a code for add a RazorPagein the in RazorViewEngine, or anywhere else that allows register in the context
          
                  System.Diagnostics.Debug.WriteLine(RazorP.GetType().ToString());
                  /*  - output 
                      AspNetCore.Views_test
                      AspNetCore.Views_TestFolder_htmlpage
          
                      as you can see is the folder structure
          
                      - folder tree:
                      Project plugin folder
                          Views
                              test.cshtml
                              TestFolder
                                  htmlpage.cshtml
          
                  */
              }
          }
          


          已解决

          感谢我所解决的所有问题,


          Solved

          thanks to all I solved, there seems to be a problem with

          var assembly = ...;
          services.AddMvc()
              .AddApplicationPart(assembly)
          

          有人甚至忘了把爵士乐零件工厂放进去

          someone forgot to even put the razzor part factory

          CompiledRazorAssemblyApplicationPartFactory

          我解决了

          services.AddMvc().ConfigureApplicationPartManager(apm =>
              {
              foreach (var b in new CompiledRazorAssemblyApplicationPartFactory().GetApplicationParts(AssemblyLoadContext.Default.LoadFromAssemblyPath(".../ViewAssembypath/file.Views.dll")))
                  apm.ApplicationParts.Add(b);
              });
          

          此外,我发布了一个库,该库可以高效地完成所有工作

          in addition I published a library that does everything efficiently

          NETCore.Mvc.PluginsManager

          推荐答案

          感谢我所解决的所有问题,

          thanks to all I solved, there seems to be a problem with

          var assembly = ...;
          services.AddMvc()
              .AddApplicationPart(assembly)
          

          有人甚至忘了把爵士乐零件工厂放进去

          someone forgot to even put the razzor part factory

          CompiledRazorAssemblyApplicationPartFactory

          我解决了

          services.AddMvc().ConfigureApplicationPartManager(apm =>
              {
              foreach (var b in new CompiledRazorAssemblyApplicationPartFactory().GetApplicationParts(AssemblyLoadContext.Default.LoadFromAssemblyPath(".../ViewAssembypath/file.Views.dll")))
                  apm.ApplicationParts.Add(b);
              });
          

          此外,我发布了一个库,该库可以高效地完成所有工作

          in addition I published a library that does everything efficiently

          NETCore.Mvc.PluginsManager

          这篇关于插件中的ASP .NET Core MVC 2.1 mvc视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆