T.S.
T.S.

Reputation: 19340

Retrieve Service and use it in some arbitrary class in net core

There are plenty of examples how to set controllers to use services etc. But what about plain old class? Lets use some simple configuration service

JSON

{
  ....,
  "AppSettings": {
    "SchemaFile": "some file name.xml"
  }  
}

POCO

public class AppSettings
{
    public string SchemaFile { get;set; }
}

In startup.cs

public void ConfigureServices(IServiceCollection services)
{
    IConfigurationSection appSettingsSection = Configuration.GetSection("AppSettings");
    services.Configure<AppSettings>(appSettingsSection);
  . . . . 
}

This is the point where all examples move directly to the controller. But we are going to have plenty of code outside controller. What I need is to access this service using provider.GetService(typeof(T)) or provider.GetRequiredService(typeof(T)), from, lets say a static class

internal static MyClass
{
    internal static void DosomeThing()
    {
        // acquire my service
        // use it to retrieve some value
        // continue with my logic

    }
}

Thanks

Upvotes: 1

Views: 3276

Answers (2)

Nkosi
Nkosi

Reputation: 247088

Just as the services can be injected into controllers, so too can they be injected into other classes.

static classes however to not lend themselves well to dependency injection by default.

Instead of using a static class, make a regular class and explicitly depend on the desired service via constructor injection

internal class MyClass : IMyService {
    readonly AppSettings settings;

    public MyClass(AppSettings settings) {
        this.settings = settings;
    }

    internal void DosomeThing() {
        // retrieve some value from settings
        // continue with my logic
    }
}

You can then register your desired POCO and utilities with the service container

public void ConfigureServices(IServiceCollection services) {
    AppSettings appSettings = Configuration.GetSection("AppSettings").Get<AppSettings>();
    services.AddSingleton(appSettings);
    services.AddSingleton<IMyService, MyClass>();
    //. . . . 
}

Inject your service where it is needed and it will have access to the POCO when being resolved for injection.

There really is no need to be passing IServiceProvider around as that can be seen as a code smell.

Simplifying your design to follow explicit dependency principle should make your code more SOLID and easier to follow and maintain.

Upvotes: 2

T-moty
T-moty

Reputation: 2797

You should pass AppSettings as parameter from the caller method

public class HomeController : Controller
{
   public HomeController(AppSettings settings)
   {
      this.Settings = settings;
   }

   private AppSettings Settings { get; }

   public IActionResult Index()
   {
      MyClass.DosomeThing(this.Settings);
   }
}

internal static MyClass
{
    internal static void DosomeThing(AppSettings settings)
    {
        // acquire my service
        // use it to retrieve some value
        // continue with my logic

    }
}

Upvotes: 0

Related Questions