Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding Mvc options separately after adding Mvc services

A question very specific to Net Core. I would like to write an extension method for for the IServiceCollection, which will do the configuration in the application.

The reason for that, if that currently, some of the components such as attribute and controller are located in separate libraries. So, I would like to write an extension method, which will take care of configuration for each of these libraries. Configuration has to be independent of main application configuration.

Here is the current code (which I don't enjoy, because of the reason above):

public void ConfigureServices(IServiceCollection services)
{
    //..
    services.AddMvc(options => {
            // is needed for the library "filters". 
            options.Filters.Add(typeof(ExternalValidationActionFilterAttribute));
        })
        // is needed for the library "controllers"
        .AddApplicationPart(typeof(ExternalController).Assembly)
        .AddControllersAsServices();

    //..
    services.AddSingleton<ExternalControllerConfiguration>(new ExternalControllerConfiguration());
    services.AddSingleton<ExternalValidationAttributeConfiguration>(new ExternalValidationAttributeConfiguration());
}

The only method from the main application is the AddMvc(). The rest of the code is specific to external libraries. I would like to avoid mixing external library specific logic with main app logic. Ideally, refactored code should look like this:

public void ConfigureServices(IServiceCollection services)
{
    //..
    services.AddMvc();
    services.ConfigureExternalAttributes();
    services.ConfigureExternalControllers();
    //..
}

and

public static class ServiceCollectionExtensions
{
    public static void ConfigureExternalAttributes(this IServiceCollection services)
    {
        // TBD: check if Mvc services added
        //      if not - add new, with options
        //      if yes - add options to existing
        //          options.Filters.Add(typeof(ExternalValidationActionFilterAttribute));

        services.AddSingleton<ExternalValidationAttributeConfiguration>(new ExternalValidationAttributeConfiguration());
    }

    public static void ConfigureExternalControllers(this IServiceCollection services)
    {
        // TBD: check if Mvc services added
        //      if not - add new, with options
        //      if yes - add options to existing
        //          1. If 'part' not present already: .AddApplicationPart(typeof(ExternalController).Assembly)
        //          2. If 'AddControllersAsServices' not present already: .AddControllersAsServices();
        //             Else: skip

        services.AddSingleton<ExternalControllerConfiguration>(new ExternalControllerConfiguration());
    }
}

My last idea was to go to the git-hub, see the source-code and to come up with some solution. BUT. Are there any common ways of achieving this result? Maybe Microsoft had thought this though already, so I am trying to re-implement the wheel?

Any advises or code samples are very welcomed.

like image 871
Alex Avatar asked Feb 25 '19 08:02

Alex


People also ask

Is ASP NET MVC discontinued?

ASP.NET MVC is no longer in active development. The last version update was in November 2018. Despite this, a lot of projects are using ASP.NET MVC for web solution development. As to JetBrains' research, 42% of software developers were using the framework in 2020.

What replaces ASP .NET MVC?

The ASP.NET Core MVC is a framework for building web apps and APIs, optimized for use with ASP.NET Core. ASP.NET MVC, a web application development framework released by Microsoft in 2009, was replaced by ASP.NET Core seven years later, an upgraded version for the same.

What is @model in Cshtml?

The @model directive allows access to the list of movies that the controller passed to the view by using a Model object that's strongly typed. For example, in the Index.cshtml view, the code loops through the movies with a foreach statement over the strongly typed Model object: CSHTML Copy.

Is Ioption a singleton?

IOptionsMonitor is a Singleton service that retrieves current option values at any time, which is especially useful in singleton dependencies.


1 Answers

For the application part, you can create custom extension class in separate library using Microsoft.Extensions.DependencyInjection package as also suggested by Kirk Larkin.

  1. Add "Microsoft.Extensions.DependencyInjection" package in your separate library.
Install-Package Microsoft.Extensions.DependencyInjection
  1. Create a new class ExternalConfigurationExtensions.cs in your separate library and update class namespace as described below.
namespace Microsoft.Extensions.DependencyInjection
{
    public static class ExternalConfigurationExtensions
    {
        public static IMvcBuilder ConfigureExternalControllers(this IMvcBuilder builder)
        {
            if (builder == null)
                throw new ArgumentNullException(nameof(builder));

            builder.AddApplicationPart(typeof(ExternalController).Assembly);

            return builder;
        }
    }
}
  1. Update your Startup.cs
services.AddMvc()
        .ConfigureExternalControllers();
like image 114
Arvind Vishwakarma Avatar answered Sep 20 '22 02:09

Arvind Vishwakarma