简体   繁体   中英

How to separate asp.net core mvc project into multiple assembly (.dll)?

How to separate asp.net core mvc project into multiple assembly (.dll)?

    • Controllers
      • HomeController.cs
    • Models
    • Views
      • Home
        • Index.cshtml
    • Controllers
      • EmployeeController.cs
    • Models
      • EMPLOYEE.cs
    • Views
      • Employee
        • Index.cshtml
    • Controllers
      • ChartAccountController.cs
    • Models
      • ACCOUNT.cs
    • Views
      • ChartAccount
        • Index.cshtml

    • HR.dll
    • HR.Views.dll
    • ACC.dll
    • ACC.Views.dll

I want to add reference those dll (HR.dll, HR.Views.dll, ACC.dll, ACC.Views.dll) into MyApp Project.

And then run MyApp project can access Employee & Chart Account module too.

*** Original Answer (Update below)

If you want to do this you'll need to do the following 2 steps:

  1. You need to load the controllers from the external dlls

There is already a solution for this on stackoverflow: How to use a controller in another assembly in ASP.NET Core MVC 2.0?

It says the following:

Inside the ConfigureServices method of the Startup class you have to call the following:

 services.AddMvc().AddApplicationPart(assembly).AddControllersAsServices(); 
  1. You need to load the your compiled Razor views, I guess this is what you have in your HR.Views.dll and ACC.Views.dll.

There is also already a solution for this on stackoverflow:

How CompiledRazorAssemblyPart should be used to load Razor Views?

Loading Razor Class Libraries as plugins

This is one possible solution from the links above:

What you need to do is:

 services.AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_1) .ConfigureApplicationPartManager(ConfigureApplicationParts); 

and configure the parts like this

  private void ConfigureApplicationParts(ApplicationPartManager apm) { var rootPath = HostingEnvironment.ContentRootPath; var pluginsPath = Path.Combine(rootPath, "Plugins"); var assemblyFiles = Directory.GetFiles(pluginsPath, "*.dll", SearchOption.AllDirectories); foreach (var assemblyFile in assemblyFiles) { try { var assembly = Assembly.LoadFile(assemblyFile); if (assemblyFile.EndsWith(".Views.dll")) apm.ApplicationParts.Add(new CompiledRazorAssemblyPart(assembly)); else apm.ApplicationParts.Add(new AssemblyPart(assembly)); } catch (Exception e) { } } } 

If you also have javascript and css files in our separate MVC projects, you will need to embed this to your dll otherwise your main app wont see it. So in your HR and ACC project, you'll need to add this in your .csproj file:

  <ItemGroup>
    <EmbeddedResource Include="wwwroot\**" />
  </ItemGroup>

And just to be clear, I agree with the other comments, I don't think it is a good architecture, but it is possible to do it if you want.

*** Updated (Worked)

Edit in method 方法中编辑

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2).ConfigureApplicationPartManager(ConfigureApplicationParts);

and method:

private void ConfigureApplicationParts(ApplicationPartManager apm)
    {
        var rootPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

        var assemblyFiles = Directory.GetFiles(rootPath , "*.dll");
        foreach (var assemblyFile in assemblyFiles)
        {
            try
            {
                var assembly = Assembly.LoadFile(assemblyFile);
                if (assemblyFile.EndsWith(this.GetType().Namespace + ".Views.dll") || assemblyFile.EndsWith(this.GetType().Namespace + ".dll"))
                    continue;
                else if (assemblyFile.EndsWith(".Views.dll"))
                    apm.ApplicationParts.Add(new CompiledRazorAssemblyPart(assembly));
                else
                    apm.ApplicationParts.Add(new AssemblyPart(assembly));
            }
            catch (Exception e) { }
        }
    }

What you're wanting is not possible, or perhaps better said: it's not a good idea, for sure.

In general, you need to use Razor Class Libraries. All common functionality would then go into those RCLs. Your entire HR and ACC projects could be RCLs, unless you need to run those independently, as full web apps, as well. In which case, you'd need a structure more like:

  • HR RCL
  • HR Web App (depends on HR RCL)
  • ACC RCL
  • ACC Web App (depends on ACC RCL)
  • Main App (depends on HR RCL and ACC RCL)

In either case, you'd put all the controllers, views, and static resources that need to be shared in the RCL, so if you do have actual HR/ACC web apps, those would be pretty light: mostly just consisting of Program and Startup and a dependency on their respective RCLs.

For more information, see the documentation on Razor Class Libraries .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM