Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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

I have 3 projects

  • MyApp Project
    • Controllers
      • HomeController.cs
    • Models
    • Views
      • Home
        • Index.cshtml
  • HR Project

    • Controllers
      • EmployeeController.cs
    • Models
      • EMPLOYEE.cs
    • Views
      • Employee
        • Index.cshtml
  • ACC Project

    • Controllers
      • ChartAccountController.cs
    • Models
      • ACCOUNT.cs
    • Views
      • ChartAccount
        • Index.cshtml

I want to compile into dll

  • HR Project
    • HR.dll
    • HR.Views.dll
  • ACC Project
    • 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.

like image 780
Sophairk Avatar asked May 17 '19 11:05

Sophairk


People also ask

Should you split your ASP NET MVC project into multiple projects?

It shouldn't! That's why it's designed in a modular way. In most web applications out there, we version and deploy all these assemblies (Web, BLL and DAL) together. So, separating a project into 3 projects does not add any values.

What is an assembly DLL?

An assembly is a collection of types and resources that are built to work together and form a logical unit of functionality. Assemblies take the form of executable (.exe) or dynamic link library (. dll) files, and are the building blocks of . NET applications.


1 Answers

*** 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)

Just a step:

Edit Startup.cs in ConfigureServices 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) { }
        }
    }
like image 179
hujtomi Avatar answered Oct 23 '22 11:10

hujtomi