Reputation: 1094
I should write a big software for a company. This company has many different departments, but each department needs the same base-functions and also some specific department features. Therefore i would like to split the functions by using different project libraries and add them to the base to minimalize the code in the base. This basic idea is shown in the image below.
To minimalize the complexity i have a sample figure which has in the basic project (base functions) the web-views /home/drawing and /home/workschedule. There are also two different departments which need some special functions which are availabe under /departmentA/special or /departmentB/special. What i would like to do is the following by code:
I would like to build one solution with a .net-core mvc project which is called basic project. There should be the functions which are necessary for each department. No other code instead of code which is general should be their. If a department needs some special features i would like to create a new project in this solution for each Department, in our example for department A and B. Each of this projects should provide controllers with views which were routed to if we call for example /departmentA/special.
Now i have different problems:
1. How could i call controllers by linked projects like DepartmentA project and deliver Views? I read something about application parts in asp.net core, but i could only access the controller-functions which could not deliver the view. I did it like the following:
I got the following error:
The solution is like Chris Pratt desribed for the previous problem. But now i have the same project structure like before but also need some special JavaScript and CSS Files for DepartmentA and DepartmentB.
This works with CommonUI (Embedded Resources + a specific resource file provider). The example therefore is the following:
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="2.1.0" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="wwwroot\**\*" />
</ItemGroup>
</Project>
2.1 First create a static class for the Startup-Call which is necessary to load initial the embedded ressources
public static class CommonUIServiceCollectionExtensions
{
public static void AddCommonUI(this IServiceCollection services)
{
services.ConfigureOptions(typeof(CommonUIConfigureOptions));
}
}
2.2 Second create a class which reads the embedded-resource folder
internal class CommonUIConfigureOptions : IPostConfigureOptions<StaticFileOptions>
{
public CommonUIConfigureOptions(IHostingEnvironment environment)
{
Environment = environment;
}
public IHostingEnvironment Environment { get; }
public void PostConfigure(string name, StaticFileOptions options)
{
name = name ?? throw new ArgumentNullException(nameof(name));
options = options ?? throw new ArgumentNullException(nameof(options));
// Basic initialization in case the options weren't initialized by any other component
options.ContentTypeProvider = options.ContentTypeProvider ?? new FileExtensionContentTypeProvider();
if (options.FileProvider == null && Environment.WebRootFileProvider == null)
{
throw new InvalidOperationException("Missing FileProvider.");
}
options.FileProvider = options.FileProvider ?? Environment.WebRootFileProvider;
// Add our provider
var filesProvider = new ManifestEmbeddedFileProvider(GetType().Assembly, "wwwroot");
options.FileProvider = new CompositeFileProvider(options.FileProvider, filesProvider);
}
}
Now i have to include it in the Startup in my main MVC Project in the ConfigureServices Method with this call:
services.AddCommonUI();
But there is the big problem. Because i have to add a using with the Razor Class Library reference. So when i switch the dependency from deployment departmentA to departmentB i have also to change the using in the basic project. Maybe someone could give me a hint.
Upvotes: 0
Views: 481
Reputation: 239290
It looks like you've got just a standard class library, where you're attempt to add views to and share from. That's not possible. The views will not be compiled into the class library, and therefore are not available to reference from that class library.
What you can do is create a Razor Class Library. Despite the name, it has more in common with an ASP.NET Core application than a class library, only there's no Program
and no Startup
(i.e. it doesn't run on its own). However, with that, the views will be embedded into the library and thus available to projects that reference it. The docs specifically focus on Razor Pages, but MVC-style views and controllers work just as well.
Upvotes: 3