Обратная совместимость внедрения зависимостей .NET Core с .NET Framework?

Я хочу перестроить библиотеку .NET Framework в .NET Core, а затем использовать эту библиотеку в приложении .NET Framework.

Библиотеке нужна строка подключения к базе данных. В .NET Core я бы использовал внедрение зависимостей, чтобы передать конфигурацию со строкой подключения в библиотечный класс.

public MyRepository(IConfiguration config)
{
    _connectionString = config.GetConnectionString("MyDb");
}

Но как я могу использовать этот класс из библиотеки .NET Framework 4.6, не внедряя сложные DI-фреймворки?


person fantastischIdee    schedule 30.03.2018    source источник


Ответы (2)


Я уже использую новые библиотеки Microsoft.Extensions в .NET Framework 4.7.1, в основном Библиотеки DependencyInjection и Configuration.

Библиотеки 2.x совместимы с .NET Standard 2.0, что означает, что их можно добавлять в приложения, предназначенные для любой среды выполнения, совместимой с .NET Standard 2.0, т. е. .NET Framework 4.7.1 и выше или .NET Core 2.0 и выше. .

В более старых средах выполнения (4.6.1 и более поздних) NuGet может потребоваться добавить некоторые дополнительные пакеты с более новыми версиями некоторых системных сборок, например System.Runtime.

Вы вообще не можете добавить пакеты расширения 2.0 в 4.6. Вы можете добавить старые версии 1.x, которые используются в .NET Core 1.x.

Настройка расширений выполняется одинаково в .NET Core и Full Framework:

  1. Вы создаете ConfigurationBuilder, добавляете поставщиков конфигурации и в конце вызываете Build(), чтобы получить объект IConfigurationRoot:

    IConfigurationRoot configRoot = new ConfigurationBuilder()
        .AddUserSecrets<Program>()
        .AddJsonFile($"appsettings.json")
        .Build();
    
  2. Создайте ServiceCollection, зарегистрируйте службы и вызовите BuildServiceProvider(), чтобы получить ServiceProvider. Вы будете использовать этот ServiceProvider для создания экземпляров классов, требующих внедрения.

ASP.NET Core, который также работает с полной платформой, предоставляет дополнительные вспомогательные библиотеки, которые скрывают шаблонный код.

IServiceCollection services = new ServiceCollection();
ServiceProvider provider= services.AddSingleton<MyService>()
                                  .AddTransient<AnotherService>()
                                  .AddTransient<ServiceThatNeedsTheOthers>()
                                  .BuildServiceProvider();

Предполагая, что третья служба:

public class ServiceThatNeedsTheOthers
{
    public ServiceThatNeedsTheOthers(MyService s1,AnotherService s2){..}
}

Вы можете создать его с помощью:

var service3=provider.GetRequiredService<ServiceThatNeedsTheOthers>();

Все это описано в колонке Марка Михаэлиса Essential .NET в журнале MSDN Magazine, например, Dependency Injection с .NET Core и Конфигурация в .NET Core. В статьях показано, как настроить и использовать расширения в консольных приложениях, где вам нужно написать весь шаблон.

PS ASP.NET Core 2.0 также может быть ориентирован на полную платформу. Для нового веб-приложения может иметь смысл создать проект ASP.NET Core 2.0, ориентированный на 4.7.1.

person Panagiotis Kanavos    schedule 30.03.2018
comment
Удалена версия 4.6 .NET Framework, так как меня интересует, как это сделать в .NET Framework, совместимом со стандартом dotnet. - person fantastischIdee; 30.03.2018
comment
Тогда используйте 4.7.1. Он совместим со Standard 2.0, поэтому ему не нужны дополнительные библиотеки. - person Panagiotis Kanavos; 30.03.2018
comment
@fantastischIdee PS ASP.NET Core 2.0 также может быть ориентирован на всю платформу, а не только на Core. Если вы хотите создать веб-приложение, вам, вероятно, следует создать проект ASP.NET Core 2.0. - person Panagiotis Kanavos; 30.03.2018
comment
@PanagiotisKanavos Я истолковал вопрос как означающий, что он хочет создать библиотеку .netstandard20, которая использует DI, на которую будет ссылаться приложение .NET Framework. Там нет упоминания о создании веб-приложения. - person McGuireV10; 30.03.2018
comment
@ McGuireV10 даже в консольных приложениях .NET Core вы должны знать, как настроить встроенный DI. Большинство примеров относятся к ASP.NET Core, где этапы установки скрыты за WebHost.CreateDefaultBuilder. - person Panagiotis Kanavos; 30.03.2018
comment
Очевидно. Вот почему я спросил, знаком ли ОП с концепцией корня композиции. Ответ изменил бы то, как я представил пример кода. Но я полагаю, он может почерпнуть это из статей, на которые вы ссылаетесь. - person McGuireV10; 31.03.2018
comment
Куда идет этот код? Нужно ли помещать ConfigurationBuilder и IServiceCollection в Global.asax.cs? - person Don Rhummy; 06.04.2019
comment
@PanagiotisKanavos о PS. Начиная с Core v3.0, вы больше не можете ориентироваться на Full Framework (devblogs.microsoft.com/aspnet/). Надеюсь, это поможет всем, кто пытается использовать последний код Core с Full Framework. Если вас устраивает Core v2.*, то все в порядке. - person sixeyes; 22.04.2020
comment
@PanagiotisKanavos, как добавить DI для ILogger с log4net в стандартную сетевую структуру? - person fededim; 31.03.2021
comment
Легко, как кусок пирога. Вы должны добавить тот же пакет сетевого ядра Microsoft.Extensions.Logging.Log4Net.AspNetCore и использовать services.AddLogging(opt => opt.AddLog4Net("log4net.config")), большое спасибо за ваш ответ. - person fededim; 31.03.2021

Сценарий, который вы описываете, предназначен для .NET Standard. достигать. Только проект библиотеки классов может быть нацелен на .netstandard, и любая такая библиотека совместима с самыми последними приложениями .NET Framework, а также с приложениями .NET Core.

Сборки .NET Core в Microsoft.Extensions.DependencyInjection и Microsoft.Extensions.Configuration также .netstandard-совместимы, что означает, что вы можете использовать их в своей библиотеке и в своих приложениях.

Итак, да, вы можете использовать .NET Core DI с .NET Framework, а в сценарии с библиотекой просто придерживаться API-интерфейсов .NET Standard, и он также будет работать со всеми реализациями .NET. У меня есть несколько очень больших и очень сложных .netstandard20 библиотек, которые я использую с приложениями, предназначенными для обеих платформ, и мне редко приходится спрашивать себя, совместим ли тот или иной API, потому что покрытие сейчас очень хорошее, но вы можете найти полный список здесь.

person McGuireV10    schedule 30.03.2018
comment
Да, я понимаю, для чего предназначен .NET Standard. Но меня интересует, как настроить приложение .NET Framework, чтобы IConfiguration была доступна для DI в MyRepository. В .NET Core за меня это делает WebHost.CreateDefaultBuilder... - person fantastischIdee; 30.03.2018
comment
Знакомы ли вы с концепцией DI корня композиции? В основном приложение отвечает за регистрацию сервисов DI, тогда конструктор DI в вашей библиотеке просто работает автоматически. (Если вашей библиотеке также необходимо зарегистрировать службы DI, добавьте в библиотеку расширение регистрации службы и вызовите его из приложения во время запуска.) Если вы не знакомы, я могу открыть другой ответ для демонстрации. - person McGuireV10; 30.03.2018
comment
@fantastischIdee 4.6 не годится. 4.6.1 возможно, просто добавьте пакеты. Настройка пакетов для консольных/неосновных приложений — это другой вопрос. - person Panagiotis Kanavos; 30.03.2018
comment
@McGuireV10 McGuireV10 Вы не можете просто добавить любую библиотеку DI без ее настройки. ASP.NET Core предоставляет вспомогательные средства, недоступные даже в консольных приложениях .NET Core. Это не вопрос о DI в целом - person Panagiotis Kanavos; 30.03.2018
comment
@PanagiotisKanavos У меня есть шесть служебных консольных программ .NET Core, которые запускают очень сложную зависимую от внедрения зависимостей библиотеку каждые 5 минут в режиме 24/7, и эта же библиотека также работает на веб-сайтах .NET Framework Azure. Не совсем уверен, что вы пытаетесь сказать, но .NET Core DI прост в использовании без ASP.NET Core. - person McGuireV10; 30.03.2018
comment
Удалена версия 4.6 .NET Framework, так как меня интересует, как это сделать в .NET Framework, совместимом со стандартом dotnet. - person fantastischIdee; 30.03.2018