ASP.NET Core 2.2 For Beginners (Part 2): Creating a Service

Creating a Service

Instead of using one specific source to fetch data, you can use services to fetch data from different sources, depending on the circumstance. This mean that you, through the use of configuration, can use different data sources according to the need at hand.

You might want to fetch data from a JSON file when building the service, and later switch to another implementation of that service, to fetch real data.

To achieve this, you create an interface that the service classes implement, and then use that interface when serving up the instances. Because the service classes implement the same interface, instances from them are interchangeable.

To get access to the services from the Configure method in the Startup class, or any other constructor, model, Razor Page, or view, you must use dependency injection. That is, pass in the interface as a parameter to the method.

You must register the service interface, and the desired service class, with the services collection in the ConfigureServices method, in the Startup class. This determines which class will be used to create the instance, when dependency injection is used to pass in an instance of a class implementing the interface.

In the upcoming example, you will inject a service class into the Configure method, but it works just as well with regular classes that you want to inject into a constructor, model, Razor Page, or view, using dependency injection. The same type of registration that you did in the ConfigureServices method could be applied to this scenario, but you wouldn’t have to implement it as a service.

You might ask how the IApplicationBuilder parameter gets populated in the Configure method, when no configuration has been added for it in the ConfigureServices method. The answer is that certain service objects will be served up for interfaces automatically by ASP.NET; one of those interfaces is the IApplicationBuilder. Another is the IHosting­Environment service, which handles different environments, such as development, staging, and production.

Example

Let’s implement an example where you create two service classes that retrieve data in two different ways. The first will simply return a hardcoded string (you can pretend that the data is fetched from a database or a web service if you like), and the second class will return the value from the Message property that you added to the appsettings.json file.

You will begin by adding an interface called IMessageService, which will define a method called GetMessage, which returns a string.

Then you will implement that interface in a service class called HardcodedMessage­Service, which will return a hardcoded string. After implementing the class, you will add configuration for it and the interface in the ConfigureServices method and test the functionality.

Then you will implement another class called ConfigurationMessageService, which reads from the application.json file and returns the value from its Message property. To use the new service class, you must change the configuration. Then you will refresh the appli­cation in the browser to make sure that the configuration value is returned.

Adding the IMessageService Interface

  1. Right click on the project node in the Solution Explorer and select Add-New Folder.
  2. Name the folder Services.
  3. Right click on the Services folder and select Add-New Item.
  4. Select the Interface template, name the interface IMessageService, and click the Add
  5. Add the public access modifier to the interface (make it public).
  6. Add a method called GetMessage, which returns a string to the interface. It should not take any parameters.
  7. Save the file.

The complete code for the interface:

public interface IMessageService
{
    string GetMessage();
}

 

Adding the HardcodedMessageService Class

  1. Right click on the Services folder and select Add-Class.
  2. Name the class HardcodedMessageService and click the Add
  3. Implement the IMessageService interface in the class by clicking on the light bulb icon that appears when you hover over the interface name when you have added it to the class. Select Implement interface in the menu that appears.
  4. Remove the code line with the throw statement and return the string Hardcoded message from a service.
  5. Save all files by pressing Ctrl+Shift+S on the keyboard.

The complete code for the HardcodedMessageService class:

public class HardCodedMessageService : IMessageService
{
    public string GetMessage()
    {
        return "Hardcoded message from a service.";
    }
}

Configure and Use the HardcodedMessageService Class

  1. Open the cs file.
  2. Locate the ConfigureServices
  3. To create instances that can be swapped for the IMessageService interface when dependency injection is used, you must add a definition for it to the services In this example, you want ASP.NET to swap out the interface with an instance of the HardcodedMessageService class. Add the definition by calling the AddSingleton method on the services object, specifying the interface as the first type and the class as the second type.

services.AddSingleton<IMessageService, HardcodedMessageService>();

  1. You need to add a using statement to the Services

using AspNetCore22Intro.Services;

  1. Now you can use dependency injection to access the IMessageService from the Configure

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IMessageService msg)
{
    ...
}

  1. Remove the line that declares the message variable from the Run
  2. Replace the message variable name in the WriteAsync method with a call to the GetMessage method on the msg object, which will contain an instance of the HardcodedMessageService

await context.Response.WriteAsync(msg.GetMessage());

  1. Save all files and run the application. The message Hardcoded message from a service should appear in the browser.

The complete code for the ConfigureServices method:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IMessageService, ardcodedMessageService>();
}

The complete code for the Configure method:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IMessageService msg)
{
    if (env.IsDevelopment())

    {
        app.UseDeveloperExceptionPage();
    }

    app.Run(async (context) =>
    {
        await context.Response.WriteAsync(msg.GetMessage());
    });
}

When adding a service to the service collection, you can choose between several Add methods. Here’s a rundown of the most commonly used.

Singleton creates a single instance that is used throughout the application. It creates the instance when the first dependency-injected object is created.

Scoped services are lifetime services, created once per request within the scope. It is equivalent to Singleton in the current scope. In other words, the same instance is reused within the same HTTP request.

Transient services are created each time they are requested and won’t be reused. This lifetime works best for lightweight, stateless services.

Add and Use the ConfigurationMessageService Class

  1. Right click on the Services folder and select Add-Class.
  2. Name the class ConfigurationMessageService and click the Add
  3. Implement the IMessageService interface in the class.
  4. Add a constructor to the class (you can use the ctor code snippet).
  5. Inject the IConfiguration interface into the constructor and name it configuration.
  6. Save the configuration object in a private class-level variable called _configuration. You can let Visual Studio create the variable for you by writing the variable name in the method, clicking the light bulb icon, and selecting Generate field…

Private readonly IConfiguration _configuration;
public ConfigurationMessageService(IConfiguration configuration)
{
    _configuration = configuration;
}

  1. You need to add a using statement to the Extensions.Configuration namespace.

using Microsoft.Extensions.Configuration;

  1. Remove the throw statement from the GetMessage method and return the string from the Message property stored in the json file. You achieve this by indexing into the Configuration object.

return _configuration["Message"];

  1. Open the cs file and locate the ConfigureServices method.
  2. Change the HardcodedMessageService type to the ConfigurationMessageService type in the AddSingleton method call.

services.AddSingleton<IMessageService, ConfigurationMessageService>();

  1. Save all files by pressing Ctrl+Shift+S on the keyboard.
  2. Run the application. You should now see the message Hello, from configuration, from the json file.

The complete code for the ConfigurationMessageService class:

public class ConfigurationMessageService : IMessageService
{
    Private readonly IConfiguration _configuration;

    public ConfigurationMessageService(IConfiguration configuration)

    {
        _configuration = configuration;
    }

    public string GetMessage()
    {
        return _configuration["Message"];
    }
}

 

The complete code for the ConfigureServices method:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IMessageService, ConfigurationMessageService>();
}

Summary

In this chapter, you created your first ASP.NET application and added only the necessary pieces to get it up and running. Throughout the first part of this book you will add new functionality using services and middleware.

You also added a configuration file, and created and registered a service to make it avail­able through dependency injection in other parts of the application.

In the next chapter, you will learn about middleware.

 

Stay connected with news and updates!

Join our mailing list to receive the latest news and updates from our team.
Don't worry, your information will not be shared.

Subscribe
Close

50% Complete

Two Step

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.