Трехуровневая архитектура .Net Core, передающая строку подключения с уровня представления на уровень данных.

У меня есть веб-API с трехуровневой архитектурой, как показано ниже:

PresentationLayer (на уровне представления у меня есть appsetting.json, где находится строка подключения)

BusinessLayer (библиотека классов)

DataLayer (библиотека классов)

Когда я все еще использовал .Net Framework, я использовал в dataLayer этот код, показанный в ссылке ниже, чтобы получить строку подключения из web.config уровня представления:

введите здесь описание изображения

Сейчас я экспериментирую с .Net Core 2.1, и я создал тот же класс на уровне данных, но он не работает. как я могу передать строку подключения с уровня представления на уровень данных наиболее эффективным способом. Есть ли аналогичный способ передачи строки подключения, когда я работал с .Net framework.

Не могли бы вы мне помочь.


person Whiplash    schedule 02.10.2018    source источник
comment
Пожалуйста, не публикуйте скриншоты своего кода, вместо этого скопируйте/вставьте исходный код в виде текста.   -  person Rui Jarimba    schedule 02.10.2018
comment
Я не думаю, что это хорошая практика - передавать строку подключения из PL в DL.   -  person Sham    schedule 02.10.2018
comment
Вы не используете Entity Framework? Если нет, то рекомендую посмотреть. По крайней мере, идите и узнайте о внедрении зависимостей.   -  person DavidG    schedule 02.10.2018
comment
@DavidG нет, я не хочу использовать Entity framework. И под инъекцией зависимостей вы подразумеваете создание appsettings.json на уровне данных?   -  person Whiplash    schedule 02.10.2018
comment
Если бы мне пришлось вернуться к прямому использованию ADO.Net, я бы кому-нибудь навредил. На самом деле почти нет необходимости избегать его использования (или другого ORM). В любом случае... нет, это совсем не то, что такое DI, вам абсолютно необходимо заняться своим исследованием.   -  person DavidG    schedule 02.10.2018
comment
@DavidG нет, я не использую ADO.NET напрямую, я использую хранимые процедуры и т. д. и т. д.   -  person Whiplash    schedule 02.10.2018
comment
Ну, вы используете ADO.Net для вызова хранимых процессов, что также может делать EF, и также помещает данные в красивые объекты.   -  person DavidG    schedule 02.10.2018
comment
@DavidG, что-то не так, что я использую ADO.NET вместо EF? Я согласен с вами, что EF - это более чистый и быстрый способ создания и структурирования кода, но я все же предпочитаю ADO.NET. Кстати, когда я создаю большие проекты, я предпочитаю использовать ADO.NET из соображений производительности. может быть я ошибаюсь, но в любом случае   -  person Whiplash    schedule 02.10.2018
comment
@Whiplash, независимо от платформы, уровень представления не имеет права знать о строках подключения. Это сдерживало даже во времена VB6. В любом случае, то, что вы называете трехуровневым, таковым не является. Это 3 уровня, которые фактически встроены в архитектуру Web API-MVC: представление, контроллер и модель.   -  person Panagiotis Kanavos    schedule 03.10.2018
comment
@Whiplash, кстати, этот класс является плохим примером и неправильным способом использования соединений. ADO.NET уже абстрагирует классы соединений и предоставляет независимые от базы данных фабричные методы, а блок using гарантирует, что соединения всегда закрываются при необходимости. Этот класс нарушает как абстракцию, так и безопасное удаление/закрытие. Все, что вам действительно нужно, это способ получить строку подключения из настроек.   -  person Panagiotis Kanavos    schedule 03.10.2018
comment
@PanagiotisKanavos 1. не могли бы вы лучше объяснить свой последний комментарий. 2. Можете ли вы объяснить, почему этот класс, используемый для получения строки подключения, неверен?   -  person Whiplash    schedule 03.10.2018
comment
@PanagiotisKanavos в первом опубликованном вами комментарии, поэтому вы говорите, что создаете файл конфигурации int dataLayer, который является библиотекой классов, и помещаете туда строку подключения.   -  person Whiplash    schedule 03.10.2018


Ответы (4)


как я могу передать строку подключения с уровня представления на уровень данных наиболее эффективным способом. Есть ли аналогичный способ передачи строки подключения, когда я работал с .Net framework.

В Asp.Net Core намного проще передать подключение к DbConnection с помощью Injection зависимости.

  • Измените DbConnection, чтобы принять connection string

    public class DbConnection
    {
    public DbConnection(string connectionString)
    {
        _sqlConnection = new SqlConnection(connectionString);
    }
    
  • Зарегистрировать DbConnection в PresentationLayer

    services.AddTransient<DbConnection>(serviceProvider => new DbConnection(Configuration.GetConnectionString("DefaultConnection")));
    
person Edward    schedule 03.10.2018
comment
Класс DbConnection находится в dataLayer, который является библиотекой классов. слой представления теперь не относится к dataLayer - person Whiplash; 03.10.2018
comment
Ссылки @Whiplash в .Net Core являются транзитивными, что означает, что если ProjectA имеет ссылку на ProjectB, а ProjectB ссылается на ProjectC, то ProjectA сможет видеть все в ProjectC. - person DavidG; 03.10.2018

Создать класс AppSettings

public static class AppSettings
{
    public static string ConnectionString { get; set; }
}

В Startup.cs

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
    BuildAppSettingsProvider();
}

public IConfiguration Configuration { get; }

private void BuildAppSettingsProvider()
{
    AppSettings.ConnectionString = Configuration["ConnectionString"];
}

теперь вы можете получить доступ к AppSettings на уровне презентации.

100% работает.

person Prabhu Manoharan    schedule 03.10.2018

Когда у вас есть несколько слоев, вы, скорее всего, используете контейнер IOC. Создайте интерфейс на уровне данных и выполните реализацию на уровне представления, а затем зарегистрируйтесь и получите его в своем контейнере IOC. Это самый чистый способ сделать это, если вы не можете передать его напрямую в свой SqlConnection.

person BrunoVT    schedule 03.10.2018

Есть (мин) 3 варианта. Я думаю, что лучше всего использовать контейнер IoC. Возможно, вы предпочитаете добавить файл appconfig на уровень БД и получить к нему доступ для конкретных настроек уровня. Или вы можете использовать механизм внедрения по умолчанию, чтобы передать IConfiguration на бизнес-уровень, а затем передать его на уровень данных через ctors.

Например

/* ----- Startup.cs ----- */
public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IxxxService, xxxBusinessService>();
}

/* ----- UI Layer ----- */
public xxxController(IxxxService xxxBusinessService)
{
   this.xxxBusinessService = xxxBusinessService;
}

/* ----- BUSINESS LAYER ----- */
/*
UI/controller knows Business service and IConfiguration objects, and default 
injector automatically creates/passes configuration object via ctor to Business layer.
*/
public xxxService(IConfiguration configuration)
{
    this.xxxRepository = new xxxRepository(configuration);
}

/* ----- DATA LAYER ----- */
public class xxxRepository: BaseRepository, IxxxRepository
{
    public xxxRepository(IConfiguration configuration)
        : base(configuration)
    {

    }
}       

public class BaseRepository{

    protected xxxDbContext context;

    public BaseRepository(IConfiguration configuration)
    {   
        var optionsBuilder = new DbContextOptionsBuilder<xxxDbContext>();

        optionsBuilder.UseSqlServer(configuration.GetSection("ConnectionString")["DefaultConnection"]);

        this.context = new xxxDbContext(optionsBuilder.Options);
    }
}
person mutlugokhan    schedule 17.01.2019