3

我可以像这样在控制器中设置 DI 应用程序

 private IOptions<AppSettings> appSettings;
 public CompanyInfoController(IOptions<AppSettings> appSettings)
 {
     this.appSettings = appSettings;
 }

但是如何在我的自定义类中像这样

  private IOptions<AppSettings> appSettings;
  public PermissionFactory(IOptions<AppSettings> appSetting)
  {
      this.appSettings = appSettings;
  }

我在 Startup.cs 中的注册是

services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
4

4 回答 4

4

“正确”的方式

在 DI 中注册您的自定义类,就像在方法中注册其他依赖项一样ConfigureServices,例如:

services.AddTransient<PermissionFactory>();

(代替AddTransient,您可以使用AddScoped,或您需要的任何其他生命周期)

然后将此依赖项添加到控制器的构造函数中:

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

现在,DI 知道PermissionFactory,可以实例化它并将其注入到您的控制器中。

如果要PermissionFactoryConfigure方法中使用,只需将其添加到它的参数列表中:

Configure(IApplicationBuilder app, PermissionFactory prov)

Aspnet 会发挥它的魔力并在那里注入课程。

“讨厌”的方式

如果你想PermissionFactory在你的代码深处实例化,你也可以用一种有点讨厌的方式来做——IServiceProviderStartup类中存储对的引用:

internal static IServiceProvider ServiceProvider { get;set; }

Configure(IApplicationBuilder app, IServiceProvider prov) {
   ServiceProvider = prov;
   ...
}

现在您可以像这样访问它:

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

同样,DI 将负责IOptions<AppSettings>注入PermissionFactory.

依赖注入中的 Asp.Net 5 文档

于 2016-04-28T02:43:14.023 回答
2

我建议不要通过AppSettings。一个类不应该依赖于模糊的东西——它应该完全依赖于它需要的东西,或者接近它。ASP.NET Core 使摆脱依赖AppSettings. 如果您的类依赖于,AppSettings那么您无法从构造函数中真正看到它依赖于什么。它可能取决于任何键。如果它依赖于更具体的接口,那么它的依赖就会更清晰、更明确,并且您可以在单元测试时模拟该接口。

您可以使用您的类需要的特定设置(或不太具体但不太宽泛的设置)和实现它的类创建一个接口 - 例如,

    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; }
    }

然后添加一个 .json 文件,fooSettings.json:

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

然后,在Startup()(在 Startup.cs 中)我们指定进入我们的内容的地方Configuration,添加 fooSettings.json:

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

最后,在ConfigureServices()(也在 Startup.cs 中)告诉它加载 的实例FooSettings,将其转换为IFooSettings(因此属性显示为只读)并为所有依赖项提供该单个实例IFooSettings

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

现在您的类——控制器、过滤器或由 DI 容器创建的任何其他东西——可以依赖于IFooSettings它,它将由 .json 文件提供。但是你可以模拟IFooSettings单元测试。

原始博客文章- 这是我的,所以我没有抄袭。

于 2016-04-28T03:13:07.997 回答
1

您也可以在非控制器类中进行依赖注入。

在你的startup课堂上,

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);     
  }
}

现在在您的自定义类中,让构造函数接受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");
}
于 2016-04-28T02:47:13.303 回答
0

如果要 DI 来操作过滤器参考ASP.NET 5 和 MVC 6服务过滤器部分中的操作过滤器、服务过滤器和类型过滤器。

于 2016-04-28T10:32:17.777 回答