In the last chapter, we have walked through the basics of ASP.Net core. These steps are the base for making strong and lasting architectures for .NET Core apps. In this chapter, we look at the layout of ASP.NET Core. We learn about the modules, Middleware, and Request Pipeline in this system. Once we know the ASP.NET Core basics, we can then talk about how dependency injection works, registering services, different ways to inject services, setting up and changing ASP.NET Core services, and using extension methods and outside libraries to better understand ASP.NET Core.

Dependency Injection in ASP.NET Core

Benefits of Dependency Injection (DI):

Dependency Injection offers several advantages:

  I) Reduced Coupling:

  • DI eliminates dependency on integration between components. In contrast, it gives the ability to depend on interfaces instead of concrete implementation.
  • Thereby this approach is going to give the systems more flexibility allowing the developers to just add new or change special blocks without having to develop the whole code part over again.

  II) Improved Testability:

  • The DI reproduces the dependencies to move them to the components, these not only allow mocking or substitution of dependencies in unit testing but also in composition during emulation.
  • This makes it possible to split a complex system into its constituents neatly and straightforwardly which in turn results in the testing of the components at a higher grade thereby improving the code quality and reliability.

  III) Modular Design:

  • DI uses the modularized structure that follows SRP if the responsibility of every component can be single-handedly contained.
  • These modules serve specific purposes, leading to two main benefits: software for the maintainable part and extensible code.

Registering Service:

Services (dependencies) will be injected by using the built-in service container (dependency injection) mechanism within the ConfigureServices method of the Startup class. Steps for Registering Services:

  I) Definition Service Interface:

  • Create an interface that defines the service's functionality. This interface acts as a contract between the service provider and its clients.

public interface IMyService

{

       void DoSomething();

}

  II) Implement Service Class:

  • Develop a class that implements the service interface. This class allows you to control all service-related operations within the feature.

public class MyService: IMyService

{

       public void DoSomething()

       {

            // Service Implementation

       }

}

  III) Register Service in ConfigureServices:

  • In the ConfigureServices method within the Startup.cs file, register the services with the built-in service container.
  • Determine the scope of the service (e.g., singleton, scoped, transient)

services.AddSingleton<IMyService, MyService>();

Injecting Services:

Services can be injected either by using constructor injection or property injection directly into the controllers, middleware, or other components.

Constructor Injection Example:

  I) Define Controller:

  • Generate a controller class (eg, MyController) that inherits from Controller or ControllerBase.

public class MyController: Controller
{
    private readonly IMyService _myService;

    public MyController(IMyService myService)
    {
        _myService = myService;
    }

    // Controller actions
}

  II) Declare Constructor:

  • Create the service injection inside the constructor.
  • ASP.NET Core is already equipped with the container DI that automatically extracts and injects the true form of implementation.

public MyController(IMyService myService)
{
    _myService = myService;
}

  III) Use Injected Service: 

  • Utilize the injected service procedure in controller actions to make use of its inherent capability.

public IActionResult Index()
{
    _myService.DoSomething();
    return View();
}

Dependency Injection (DI) in ASP.NET Core involves declaring service interfaces, providing concrete implementations of these interfaces, registering services within the ConfigureServices method of the Startup class, and finally, injecting the services into controllers or other components using constructors.

This approach not only addresses dependency management but also promotes testability and modular design, making it easier to develop and maintain applications up to the highest standards.

Configuring and Customizing ASP.NET Core Services

It is now time to get into the detail of how you configure as well as customize ASP.NET Core services.

ConfigureServices Method:
The `ConfigureServices` method in the `Startup` class is where you configure services for your ASP.NET Core application. This would require defining database relations, establishing the logging configuration, enabling authentication, and registering custom services. Steps for Configuring Services:
  1) Define Service Configuration:
  • In the `Startup.cs` file, find the `ConfigureServices` method which is in this file.
  • It operates by implementing an `IServiceCollection` parameter, providing a place for registering and configuring the services they require.

  2) Registering Database Context (DbContext):

  • Use `services.AddDbContext<MyDbContext>` to register your DbContext class.
  • Initialize the environment variables as per your project specifications like the connection string using the `options` parameter.

services.AddDbContext<MyDbContext>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

  3) Adding Authentication:

  • Implement `services.AddAuthentication` in your application that is required for authentication.
  • specify the authentication scheme, such as "MyScheme" in the example, and then configure the authentication options (e.g., cookie authentication).

services.AddAuthentication("MyScheme")
    .AddCookie("MyScheme", options =>
    {
        // Configure cookie authentication options
});

  4) Configuring Logging:

  • Use `services.AddLogging` to set up logging services' settings.
  • Add Console logging, log for debugging, or third-party logging providers.

services.AddLogging(builder =>
{
    builder.AddConsole();
    builder.AddDebug();
});

  5) Registering Custom Services:

  • Apply `services.AddSingleton`, `services.AddScoped`, or `services.AddTransient` wherever custom services should be registered into the DI container.
  • Write the code of the service interface and implementation.

services.AddSingleton<IMyService, MyService>();

Customizing Services:

  I) Configure Options:

  • Specify classes where configurable inputs (e.g., MyOptions) are stored. Since the services.Configure<TOptions> method can handle bindings of configuration sections from appsettings.json and other sources, it is very useful to configure these classes using i

services.Configure<MyOptions>(Configuration.GetSection("MyOptions")):

  II) Use Options in Services:

  • Get values from the inner service through constructor injection.

public class MyService
{
    public MyService(IOptions<MyOptions> options)
    {
        var myConfigValue = options.Value.MyConfigProperty;
        // Use configuration values
    }
}

Extension Methods and Third-Party Libraries:

  I) Use Extension Methods: 

  • Build extension methods as a means to encapsulate the code setting up for complex through to setup steps service configurations.

public static class ServiceExtensions
{
    public static IServiceCollection AddCustomServices(this IServiceCollection services)
    {
        services.AddSingleton<IMyService, MyService>();
        // Add other custom services
        return services;
    }
}

  II) Third-Party Libraries: 

  • Leverage third-party software libraries and extensions to develop custom programs or connect with external provisions.
  • Configure and set up library-specific documentation for config instructions.

The chapter ends by talking about the ASP.NET Core service setup. It uses the `ConfigureServices` method to set up services with option patterns and add third-party tools using extension methods. These steps form the foundation for building stable and scalable architectures for .NET Core applications.Next, in Part 3, we embark on a comprehensive guide to API Development With .NET. In this part, we'll cover CRUD Operations, Defining Model Classes for Entities, Implementing Controllers for CRUD Operations, Handling HTTP Requests and Responses, and more.