简体   繁体   中英

Inject a service with parameters in Asp.Net Core, where one parameter is a nested service and the other parameters are usual variables

How to pass several parameters into a constructor, where one of the parameters is a nested service, and the second parameter is an ordinary variable. I have seen articles explaining how to do this with a nested service. It is recommended to do it with a Factory. But I have one more parameter. Below is an example of what my service looks like.

class RootService : IRootService
{
   private readonly ILogger<RootService> _logger;
   private bool _myParam;

   public RootService(ILogger<RootService> logger, bool myParam) =>
      (_logger, _myParam) = (logger, myParam);
 
}

Below is an example of what dependency registration looks like.

serviceCollection.AddSingleton(<IRootService, RootService>( _ => new RootService(myParam)));

ILogger is injected automatically by the framework behind the scenes.

This is one of the scenarios that the options pattern was created for.

  1. Create your strongly-typed options class:
public class RootServiceOptions
{
    public bool MyParam { get; set; }
}
  1. Change your constructor to accept an instance of IOptions<RootServiceOptions> :
class RootService : IRootService
{
   private readonly ILogger<RootService> _logger;
   private readonly bool _myParam;

   public RootService(ILogger<RootService> logger, IOptions<RootServiceOptions> options) =>
      (_logger, _myParam) = (logger, options.Value.MyParam);
}
  1. Create and populate RootServiceOptions in Startup.cs / ConfigureServices using the Configure extension method :
// o is of type RootServiceOptions and is the instance that will be injected
services.Configure<RootServiceOptions>(o => o.MyParam = <boolean value from somewhere>);
  1. Profit.

You should listen to the articles you've read that mention factories as that's definitely good advice.

The .net core container has good support for inline factories at your composition root for weird scenarios. I agree with Ihor in part, although IOptions<T> is if something is being loaded from a config file.

Really, it depends on your intended use cases. After all, your code should be SOLID and your classes should be honest about their dependencies via constructor definitions.

A nested dependency sounds a bit odd, as things like that should be taken care of by your container. The container can then make your services that need services! That's its job and If this isn't possible, you probably need to rethink your design to be less coupled and more abstract. Where everything has a single responsibility and is injectable as a service. Think SOLID.

If any of your constructor dependencies require primitive types or take strings, then that is something you should register within a factory at your composition root.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM