Внедрение зависимостей, конструктор с пользовательским и простым объектом - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть следующий класс -

public class GCCUPCCodeGenerator : IUPCCodeGenerator
{
    IPersistence _persistence;
    string _gccPrefix;

    public GCCUPCCodeGenerator(IPersistence persistence , string gccPrefix)
    {
        _persistence = persistence;
    }

Как мне выполнить внедрение зависимостей для этого объекта в Startup.cs?

Вот что я знаю -

A. Если бы этот класс просто нуждался в классе IPersistence, я бы добавил -

   services.AddScoped<IPersistence, Persistence>();

B. И, наконец, если бы это был класс с простымтипы в конструкторе, я знаю, как читать значения из Config для создания объекта.

Для класса UnixConnection -

public class UnixConnection : IUnixDataStore
{
    public UnixConnection(UnixConnectionOption connectionOptions)
    {

Startup.cs -

services.AddScoped<IUnixDataStore>(provider => ConfigureUnixConnectionObject());
IUnixDataStore ConfigureUnixConnectionObject()
    {
        var connectionParam = new UnixConnectionOption
        {
            DBPort = Convert.ToInt32(Configuration["DBPort"]),
            SSHUserName = Configuration["SSHUserName"],
            SSHHostName = Configuration["SSHHostName"],
            SSHPassword = Configuration["SSHPassword"],
            SQLHostName = Configuration["SQLHostName"],
            SQLUserName = Configuration["SQLUserName"],
            SQLPassword = Configuration["SQLPassword"],
            SQLDatabaseName = Configuration["SQLDatabaseName"]
        };
        return new UnixConnection(connectionParam);
    }

1 Ответ

0 голосов
/ 18 февраля 2019

Вы должны использовать перегрузку действия провайдера, почти так же, как во втором сценарии (что по иронии судьбы не нужно для этого).

services.AddScoped<IUPCCodeGenerator>(p =>
{
    // `p` is a scoped instance of `IServiceProvider`, meaning you can pull services from it
    var persistence = p.GetRequiredService<IPersistence>();
    return new GCCUPCCodeGenerator(persistence, "prefix");
});

ПрефиксКонечно, это может быть из вашей конфигурации.

Не относится к вашему вопросу, но, поскольку я упомянул, что вам не нужно делать это для вашего IUnixDataStore.Если в вашем конфиге используются разделы (что и должно быть, поскольку наличие в корне множества несвязанных настроек конфигурации может привести к путанице и ошибкам), вы можете связать раздел для UnixConnectionOptions через строго типизированный конфиг.Предполагая, что конфигурация выглядит следующим образом:

{
    "UnixConnection": {
      "DBPort": "...",
      "SSHUserName": "...",
      ...
    }
}

(Примечание: если вы используете что-то вроде переменных среды, вы можете «разделить», используя :, то есть UnixConnection:DBPort)

Тогда:

services.Configure<UnixConnectionOption>(Configuration.GetSection("UnixConnection"));

После этого у вас есть несколько вариантов.Если вы не против ввести IOptions<UnixConnectionOption> или IOptionsSnapshot<UnixConnectionOption>, тогда все готово.Это на самом деле имеет преимущество, поскольку вы можете воспользоваться такими вещами, как перезагрузка конфигурации.

Если вы действительно хотите придерживаться непосредственного введения UnixConnectionOptions, то вам просто нужно добавить еще одну строку, например:

services.AddScoped<UnixConnectionOptions>(p =>
    p.GetRequiredService<IOptions<UnixConnectionOptions>>().Value);

services.AddScoped<IUnixDataStore, UnixConnection>();

Поскольку требуемая зависимость находится непосредственно в коллекции сервисов, ее можно внедрить напрямую, без необходимости предоставления настраиваемого действия.Или вы можете придерживаться того, как вы это делаете в настоящее время, но, по крайней мере, воспользоваться сокращенным кодом:

services.AddScoped<IUnixDataStore>(p => {
    var connectionParam = p.GetRequiredService<IOptions<UnixConnectionOption>>();
    return new UnixConnection(connectionParam.Value);
);
...