[英].NET Core dependency injection to inject multiple dependencies
I'm trying to use .NET core dependency injection but can't understand how to inject dependency for my scenario.我正在尝试使用 .NET 核心依赖注入,但无法理解如何为我的场景注入依赖。 I've an interface我有一个界面
public interface IDataProvider()
{
public int GetData()
}
This interface was implemented by two classes该接口由两个类实现
public class GoldCustomer:IDataProvider
{
public int GetData()
{
//implementation for gold customer
}
}
another class另一个 class
public class SilverCustomer:IDataProvider
{
public int GetData()
{
//implementation for silver customer
}
}
Now I'm trying to configure dependency现在我正在尝试配置依赖项
public void ConfigureServices(IServiceCollection services)
{
//here i want to inject either gold customer or silver customer based on the scenario
services.AddTransient<IDataProvider, GoldCustomer>();
}
Is it possible to inject dependency based on some condition?是否可以根据某些条件注入依赖项?
Create new interface for GoldCustomer and SilverCustomer.为 GoldCustomer 和 SilverCustomer 创建新接口。 Don't need to add GetData in IGoldCustomer and ISilverCustomer as it has IDataProvider's GetData() already.不需要在 IGoldCustomer 和 ISilverCustomer 中添加 GetData,因为它已经有 IDataProvider 的 GetData()。
public interface ISilverCustomer : IDataProvider
{
}
public interface IGoldCustomer : IDataProvider
{
}
Then inject dependency in Startup.cs然后在Startup.cs中注入依赖
services.AddTransient<IGoldCustomer, GoldCustomer>();
services.AddTransient<ISilverCustomer, SilverCustomer>();
I hope what you are trying achieve after applying dependency injection as demonstrated by @Asherguru Answer Or you can apply Strategy pattern example illustrated below我希望您在应用依赖注入后尝试实现的目标,如@Asherguru Answer 所示,或者您可以应用下面说明的策略模式示例
namespace DemoInject.Services
{
public interface IStrategy
{
public int GetData();
}
}
namespace DemoInject.Services
{
public interface IDiamondCustomer: IStrategy
{
}
public class DiamondCustomer : IDiamondCustomer
{
public int GetData()
{
return 5000;
}
}
}
namespace DemoInject.Services
{
public interface ISilverCustomer: IStrategy
{
}
public class SilverCustomer : ISilverCustomer
{
public int GetData()
{
return 2000;
}
}
}
On Start up class启动时 class
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IDiamondCustomer, DiamondCustomer>();
services.AddTransient<ISilverCustomer, SilverCustomer>();
services.AddControllers();
}
And On Controller和 Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DemoInject.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace DemoInject.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
private IStrategy strategy;
private IDiamondCustomer diamondCustomer;
private ISilverCustomer silverCustomer;
public WeatherForecastController(ILogger<WeatherForecastController> logger, IDiamondCustomer diamondCustomer, ISilverCustomer silverCustomer)
{
_logger = logger;
this.diamondCustomer = diamondCustomer;
this.silverCustomer = silverCustomer;
}
[HttpGet("CheckOperation/{Id}")]
public int CheckOperation(int Id)
{
//Basically identify customer if a is even then silver else diamond
if (Id % 2 == 0)
{
this.strategy = this.silverCustomer;
}
else
{
this.strategy = this.diamondCustomer;
}
return this.strategy.GetData();
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
}
Call to CheckOperation with number even will result to Silver call and Diamond to else使用数字偶数调用 CheckOperation 将导致 Silver 调用和 Diamond 调用 else
You can inject the dependencies of both classes into the project, and then you can put the parameters GoldCustomer
or SilverCustomer
that your current project needs to use in the appsetting.json file, and then decide which class to get the data returned by obtaining the parameters of the appsetting.可以将这两个类的依赖都注入到项目中,然后可以把你当前项目需要用到的参数GoldCustomer
或者SilverCustomer
放在appsetting.json文件中,然后通过获取参数来决定从哪个class获取返回的数据的应用程序。
In appsetting.json file:在 appsetting.json 文件中:
"AppSettings": {
"CurrentCustomer": "SilverCustomer"
}
Create this class to get value from appsetting.json file:创建此 class 以从 appsetting.json 文件中获取值:
public class AppSettings
{
public string CurrentCustomer { get; set; }
}
Inject IDataProvider and AppSettings in startup.cs:在 startup.cs 中注入 IDataProvider 和 AppSettings:
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddScoped<IDataProvider, GoldCustomer>();
services.AddScoped<IDataProvider, SilverCustomer>();
Here is the class:这是 class:
public interface IDataProvider
{
public int GetData();
}
public class GoldCustomer : IDataProvider
{
public int GetData()
{
return 100;
}
}
public class SilverCustomer : IDataProvider
{
public int GetData()
{
return 200;
}
}
Controller: Controller:
public class HomeController : Controller
{
private readonly IEnumerable<IDataProvider> _dataProviders;
private AppSettings AppSettings { get; set; }
public HomeController(MyDbContext context, IEnumerable<IDataProvider> dataProviders, IOptions<AppSettings> settings)
{
_dataProviders = dataProviders;
AppSettings = settings.Value;
}
public IActionResult Index()
{
// this will get the data 200 which returned by SilverCustomer because the AppSettings.CurrentCustomer is SilverCustomer
var message = _dataProviders.FirstOrDefault(h => h.GetType().Name == AppSettings.CurrentCustomer)?.GetData();
}
}
More details, you can also refer to this .更多细节,你也可以参考这个。
Here is the test result:这是测试结果:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.