Skip to content

ASP.NET Core Controllers

Automagic registration

Thanks to the scaffolding provided by the Suite Framework, most of the time you won't need to manually write ASP.NET Controllers, but rather you would just write Application services.

However, for those cases where you need to have a more fine-grained control (pun totally intended) over the presentation layer of your application, you can always write your controllers as you would in any other ASP.NET Core application.

How you register said controller with the Suite Framework boils down to where your controller is defined:

  • Is it part of an Assembly of a Suite Module that is a dependency (direct or indirect) of your App? Then you're in luck, your controller will be automatically registered.
  • is it part of a 3rd party or non Suite Module Assembly? Then keep reading.

Manual registration

There are currently two ways in which a Suite Module can provide External controllers to the Suite Framework, both involving how the EndpointsModule is configured:

  1. Providing a whole Assembly.
C#
internal class ExternalControllerModule : SuiteModule
{
    public override void SetupModule(IModuleBuilder builder)
    {
        builder.DependsOn<EndpointsModule, EndpointsModuleOptions>(options =>
        {
            options.ExternalControllerAssemblies.Add(
                AssemblyContainingExternalControllers);
        });
    }
}
  1. Providing specific Controller types.
C#
internal class ExternalControllerModule : SuiteModule
{
    public override void SetupModule(IModuleBuilder builder)
    {
        builder.DependsOn<EndpointsModule, EndpointsModuleOptions>(options =>
        {
            options.ExternalControllers.Add(
                typeof(ThirdPartyCurrencyController));
        });
    }
}

Implicit registration

ASP.NET Core, when adding the MVC feature (using AddMvc and AddControllers) performs an scan for assemblies which were decorated with ApplicationPartAttribute.

Taking as an example the assembly generated from the Samples.EndpointsModuleSample.AppModule project (inspected with DotPeek):

Text Only
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v3.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Tsynch.Suite.Samples.EndpointsModuleSample.AppModule")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Tsynch.Suite.Samples.EndpointsModuleSample.AppModule")]
[assembly: AssemblyTitle("Tsynch.Suite.Samples.EndpointsModuleSample.AppModule")]
[assembly: ApplicationPart("ITsynch.Suite.App.MvcModule")]
[assembly: ApplicationPart("ITsynch.Suite.App.SwaggerModule")]
[assembly: ApplicationPart("ITsynch.Suite.Samples.EndpointsModuleSample.ThirdPartyControllersProject01")]
[assembly: ApplicationPart("ITsynch.Suite.Samples.EndpointsModuleSample.ThirdPartyControllersProject02")]
[assembly: ApplicationPart("Swashbuckle.AspNetCore.SwaggerGen")]
[assembly: AssemblyVersion("1.0.0.0")]

We can see all the ApplicationPartAttribute were added to it (since it was the compiled assembly) for each referenced assembly which referenced MVC.

Warning

However this implicit registration is not enough at the time being because the aforementioned scan starts from the Assembly matching the IHostingEnvironment.ApplicationName which in our case is ITsynch.Suite.Application.AspNet

Resources

  1. AspNetCore issue 16522
  2. Application Parts manager extension
  3. Internal team discussion for work item
  4. When ASP NET Core can't find your controller