ASP.NET 5 DI app setting outside controller

后端 未结 4 984

I can DI app setting in the controller like this

 private IOptions appSettings;
 public CompanyInfoController(IOptions appS         


        
相关标签:
4条回答
  • 2021-01-21 05:58

    If you want to DI to action filter reference to Action filters, service filters and type filters in ASP.NET 5 and MVC 6 service filter part.

    0 讨论(0)
  • 2021-01-21 06:00

    You can do dependency injection in your non-controller classes as well.

    In your startup class,

    public class Startup
    {
      public IConfigurationRoot Configuration { get; set; }
    
      public Startup(IHostingEnvironment env)
      {
            // Set up configuration sources.
         var builder = new ConfigurationBuilder()
                 .AddJsonFile("appsettings.json")
                 .AddEnvironmentVariables();
         Configuration = builder.Build();
      }
      public void ConfigureServices(IServiceCollection services)
      {
         // register other dependencies also here
         services.AddInstance<IConfiguration>(Configuration);     
      }
    }
    

    Now in your custom class, Have the constructor accept an implementation of IConfiguration

    private IConfiguration configuration;
    public PermissionFactory(IConfiguration configuration)
    {
      this.configuration = configuration;
    }
    public void SomeMethod()
    {
      var someSection = this.configuration.GetSection("SomeSection");
      var someValue= this.configuration.Get<string>("YourItem:SubItem");
    }
    
    0 讨论(0)
  • 2021-01-21 06:07

    The "proper" way

    Register your custom class in the DI, the same way you register other dependencies in ConfigureServices method, for example:

    services.AddTransient<PermissionFactory>();
    

    (Instead of AddTransient, you can use AddScoped, or any other lifetime that you need)

    Then add this dependency to the constructor of your controller:

    public CompanyInfoController(IOptions<AppSettings> appSettings, PermissionFactory permFact)
    

    Now, DI knows about PermissionFactory, can instantiate it and will inject it into your controller.

    If you want to use PermissionFactory in Configure method, just add it to it's parameter list:

    Configure(IApplicationBuilder app, PermissionFactory prov)
    

    Aspnet will do it's magic and inject the class there.

    The "nasty" way

    If you want to instantiate PermissionFactory somewhere deep in your code, you can also do it in a little nasty way - store reference to IServiceProvider in Startup class:

    internal static IServiceProvider ServiceProvider { get;set; }
    
    Configure(IApplicationBuilder app, IServiceProvider prov) {
       ServiceProvider = prov;
       ...
    }
    

    Now you can access it like this:

    var factory = Startup.ServiceProvider.GetService<PermissionFactory>();
    

    Again, DI will take care of injecting IOptions<AppSettings> into PermissionFactory.

    Asp.Net 5 Docs in Dependency Injection

    0 讨论(0)
  • 2021-01-21 06:14

    I recommend not passing AppSettings. A class shouldn't depend on something vague - it should depend on exactly what it needs, or close to it. ASP.NET Core makes it easier to move away from the old pattern of depending on AppSettings. If your class depends on AppSettings then you can't really see from the constructor what it depends on. It could depend on any key. If it depends on a more specific interface then its dependency is clearer, more explicit, and you can mock that interface when unit testing.

    You can create an interface with the specific settings that your class needs (or something less specific but not too broad) and a class that implements it - for example,

        public interface IFooSettings
        {
            string Name { get; }
            IEnumerable Foos { get; }
        }
    
        public interface IFoo
        {
            string Color { get;  }
            double BarUnits { get;  }
        }
    
        public class FooSettings : IFooSettings
        {
            public string Name { get; set; }
            public List<Foo> FooList { get; set; }
    
            public IEnumerable Foos
            {
                get
                {
                    if (FooList == null) FooList = new List<Foo>();
                    return FooList.Cast<IFoo>();
                }
            }
        }
    
        public class Foo : IFoo
        {
            public string Color { get; set; }
            public double BarUnits { get; set; }
        }
    

    Then add a .json file, fooSettings.json:

        {
          "FooSettings": {
            "Name": "MyFooSettings",
            "FooList": [
              {
                "Color": "Red",
                "BarUnits": "1.5"
              },      {
                "Color": "Blue",
                "BarUnits": "3.14159'"
              },      {
                "Color": "Green",
                "BarUnits": "-0.99999"
              }
            ]
          }
        }
    

    Then, in Startup() (in Startup.cs) where we specify what goes into our Configuration, add fooSettings.json:

        var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
            .AddJsonFile("config.json")
            .AddJsonFile($"config.{env.EnvironmentName}.json", optional: true)
            .AddJsonFile("fooSettings.json");
    

    Finally, in ConfigureServices() (also in Startup.cs) tell it to load an instance of FooSettings, cast it as IFooSettings (so the properties appear read-only) and supply that single instance for all dependencies on IFooSettings:

        var fooSettings = (IFooSettings)ConfigurationBinder.Bind<FooSettings>(
            Configuration.GetConfigurationSection("FooSettings"));
        services.AddInstance(typeof (IFooSettings), fooSettings);
    

    Now your class - controller, filter, or anything else created by the DI container - can have a dependency on IFooSettings and it will be supplied from the .json file. But you can mock IFooSettings for unit testing.

    Original blog post - it's mine so I'm not plagiarizing.

    0 讨论(0)
提交回复
热议问题