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 IHostingEnvironment service, which handles different environments, such as development, staging, and production.
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 HardcodedMessageService, 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 application in the browser to make sure that the configuration value is returned.
The complete code for the interface:
public interface IMessageService
{
string GetMessage();
}
The complete code for the HardcodedMessageService class:
public class HardCodedMessageService : IMessageService
{
public string GetMessage()
{
return "Hardcoded message from a service.";
}
}
services.AddSingleton<IMessageService, HardcodedMessageService>();
using AspNetCore22Intro.Services;
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IMessageService msg)
{
...
}
await context.Response.WriteAsync(msg.GetMessage());
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.
Private
readonly IConfiguration _configuration;
public ConfigurationMessageService(IConfiguration configuration)
{
_configuration = configuration;
}
using Microsoft.Extensions.Configuration;
return _configuration["Message"];
services.AddSingleton<IMessageService, ConfigurationMessageService>();
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>();
}
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 available through dependency injection in other parts of the application.
In the next chapter, you will learn about middleware.
Join our mailing list to receive the latest news and updates from our team.
Don't worry, your information will not be shared.
50% Complete
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.