Код: Выделить всё
public class MotorController
{
private readonly IMotor _motor;
public MotorController([FromKeyedServices("AxisX")] IMotor motor)
{
_motor = motor;
}
}
Примечание: я понимаю, что, вероятно, нет веских причин для этого. в приложениях ASP.NET, составляющих подавляющее большинство проектов C#. Однако для более нишевых приложений, над которыми я работаю, это будет полезным способом реализации нескольких экземпляров реальных физических устройств.
Препятствием для использования этого является то, что в настоящее время не существует способа ключа и сопоставления экземпляров IOptions, которые внедряются в классы; см. этот пример (максимально упрощенный):
Код: Выделить всё
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
// Create a simple configuration (stand-in for JSON file, etc.)
var configBuilder = new ConfigurationBuilder();
configBuilder.AddInMemoryCollection(new Dictionary
{
{ "Motors:X:AxisNumber", "1"},
{ "Motors:Y:AxisNumber", "2"},
{ "Motors:Z:AxisNumber", "3"}
});
var config = configBuilder.Build();
// Create a service collection with keyed services for different instances of the same type
var serviceCollection = new ServiceCollection();
serviceCollection.AddKeyedSingleton("X");
serviceCollection.AddKeyedSingleton("Y");
serviceCollection.AddKeyedSingleton("Z");
// QUESTION: How do we map different config sections to different keyed services?
serviceCollection.Configure(config.GetSection("Motors:X"));
var serviceProvider = serviceCollection.BuildServiceProvider();
var motorX = serviceProvider.GetRequiredKeyedService("X");
var motorY = serviceProvider.GetRequiredKeyedService("Y");
var motorZ = serviceProvider.GetRequiredKeyedService("Z");
Console.WriteLine("Motor X Axis: " + motorX.AxisNumber);
Console.WriteLine("Motor Y Axis: " + motorY.AxisNumber);
Console.WriteLine("Motor Z Axis: " + motorZ.AxisNumber);
public class Motor
{
public Motor(IOptions options)
{
AxisNumber = options.Value.AxisNumber;
}
public int AxisNumber { get; }
}
public class MotorOptions
{
public int AxisNumber { get; set; }
}
Код: Выделить всё
Motor X Axis: 1
Motor Y Axis: 1
Motor Z Axis: 1
Код: Выделить всё
MotorOptions optionsX = new();
MotorOptions optionsY = new();
MotorOptions optionsZ = new();
config.Bind("Motors:X", optionsX);
config.Bind("Motors:Y", optionsY);
config.Bind("Motors:Z", optionsZ);
// Create a service collection with keyed services for different instances of the same type
serviceCollection.AddKeyedSingleton("X", new Motor(Options.Create(optionsX)));
serviceCollection.AddKeyedSingleton("Y", new Motor(Options.Create(optionsY)));
serviceCollection.AddKeyedSingleton("Z", new Motor(Options.Create(optionsZ)));
Есть идеи по поводу более изящного решения этой проблемы, или это слишком далеко за пределами предполагаемого использования служб с ключами?
Подробнее здесь: https://stackoverflow.com/questions/786 ... o-key-inje