Nano Hash - криптовалюты, майнинг, программирование

Как получить доступ к строке подключения к БД в DAL из уровня представления

У меня есть проект веб-API .net core 2.0 с несколькими уровнями, то есть Presentation, BLL, DAL ... У меня есть строка подключения в файле appsettings.json, который присутствует на уровне презентации. Мой DAL отвечает за получение данных из БД на основе этой строки подключения. Как мне прочитать этот файл json или передать строку подключения в DAL.
P.S. Уровень представления зависит от BLL, а BLL зависит от DAL.

appsettings.json

{
  "Logging": {
    "IncludeScopes": false,
    "Debug": {
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "Console": {
      "LogLevel": {
        "Default": "Warning"
      }
    }
  },
  "ConnectionStrings": {
    "MsSqlConnectionString": "Data Source=myServerName;Database=myDB;User Id=myUserID;Password=myPWd;"
  }
}


DAL класс

protected readonly string _connectionString;
protected IDbConnection _connection { get { return new SqlConnection(_connectionString); } }

public BaseDal()
{
    _connectionString = "<<How to get connectionstring from appsetting.json>>";
}


ЧайлдДАЛ

public class MyDAL : BaseDal, IMyDAL
{
    ILogger _log;
    public MyDAL(ILoggerFactory loggerFactory)
    {
        _log = loggerFactory.CreateLogger("ChildDAL");
    }
    public async Task<IEnumerable<MyModel>> MyMethod(Dto criteria)
    {
        StringBuilder sql = new StringBuilder();

        sql.Append("SELECT * FROM table");
        string query = sql.ToString();
        // custom mapping
        DapperCustomMapping<MyModel>();

        using (IDbConnection dbConnection = _connection)
        {
            return await dbConnection.QueryAsync<MyModel>(query);
        }
    }
}

Startup.cs

public class Startup
{
    public IConfigurationRoot Configuration { get; }

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
             .SetBasePath(env.ContentRootPath)
             .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

        Configuration = builder.Build();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        //loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();
        loggerFactory.AddLog4Net();

        app.UseErrorWrappingMiddleware();
        app.UseStatusCodePagesWithReExecute("/error/{0}");
        app.UseExceptionHandler("/error/500");

        // CORS: UseCors with CorsPolicyBuilder.
        app.UseCors("AllowSpecificOrigin");

        // MVC
        app.UseMvc();

        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger();

        //Enable middleware to serve swagger - ui
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("../swagger/v1/swagger.json", "My API v1");
        });
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        // Read appsettings.json to get allowed origins
        var whiteList = new List<string>();
        var myArraySection = Configuration["AllowedOrigin"];
        if (!String.IsNullOrEmpty(myArraySection))
        {
            foreach (var d in myArraySection.Split(','))
            {
                whiteList.Add(d.Trim());
            }
        }

        // CORS
        services.AddCors(options =>
        {
            options.AddPolicy("AllowSpecificOrigin",
                policy => policy.WithOrigins(whiteList.ToArray()));
        });

        // Add framework services.
        services.AddMvc(options =>
        {
            // install global fitler on all controllers and actions.
            options.Filters.Add(new CorsAuthorizationFilterFactory("AllowSpecificOrigin"));
            options.Filters.Add(new ValidateModelAttribute());
        })
        // tell how to find the fluent validations
        .AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<ContactQueryDtoValidator>());

        // Register the Swagger generator
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info { Title = "API", Version = "v1" });
        });

        return ConfigureIoC(services);
    }

    public IServiceProvider ConfigureIoC(IServiceCollection services)
    {
        var container = new Container();
        container.Configure(config =>
        {
            config.Scan(_ =>
            {
                _.AssemblyContainingType(typeof(Startup)); // web api
                _.AssemblyContainingType(typeof(HelloBLL)); // Unused BLL
                _.AssemblyContainingType(typeof(HelloDAL)); // Unused DAL
                _.TheCallingAssembly();
                _.WithDefaultConventions();

            });

            config.Populate(services);
        });
        return container.GetInstance<IServiceProvider>();
    }
}

  • Попробуйте следующее: stackoverflow.com/questions/45030383/ 23.04.2018
  • Где строка подключения передается в DAL? 23.04.2018
  • Как вы создаете экземпляры BaseDal? 23.04.2018
  • @KirkLarkin А вот и правильный вопрос. Я наследую BaseDAL. См. Мой обновленный вопрос 23.04.2018
  • Вы регистрируете MyDAL в DI? Если да, можете ли вы включить код, чтобы я мог дать пример решения? 23.04.2018
  • @KirkLarkin Добавил мой класс startup.cs 23.04.2018
  • Вам понадобится решение, подобное тому, что предлагает @Manoj - передайте IOptions<T> в ваш MyDAL конструктор и передайте его базе BaseDal. Другой вариант - переопределить регистрацию DI и предоставить конструктору само значение connectionString. Я не знаком с StructureMap, поэтому не буду приводить код. 24.04.2018

Ответы:


1

Другой метод доступа к файлу конфигурации, на который есть ссылка в https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1&tabs=basicconfiguration

Убедитесь, что вы импортируете библиотеки ниже

using Microsoft.Extensions.Configuration;
using System.IO;

    public BaseDal()
    {
        var builder = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json");

        Configuration = builder.Build();
        var _connectionString = Configuration.GetConnectionString("CONNECTION_STRING")
    }
23.04.2018
  • Ошибка: имя «Конфигурация» не существует в текущем контексте. Затем после импорта System.Configuration я получаю сообщение об ошибке: тип или имя пространства имен GetConnectionString не существует в пространстве имен System.Configuration (вам не хватает ссылки на сборку?) 23.04.2018
  • Моя ошибка: если вы посмотрите в свой класс startup.cs, вы найдете поле Configuration, которое можно использовать для ссылки на файл appsettings.json. 23.04.2018
  • его использование Microsoft.Extensions.Configuration. После использования я получаю Configuration как null, а затем объект ref not set error. public IConfigurationRoot Configuration; protected readonly string _connectionString; _connectionString = Configuration.GetConnectionString("MsSqlConnectionString"); 23.04.2018
  • Не могу ошибиться со следующим вариантом, я не знаю чистого способа ссылаться на строку подключения. 23.04.2018
  • НП! Спасибо, что изучили это. 23.04.2018

  • 2

    Предположим, вы зарегистрировали раздел в файле startup.cs уровня представления.

      public class AppSettings
        {
            public string MsSqlConnectionString{ get; set; }
        }
    
       //registering in ConfigureServices method of Startup.cs
       services.Configure<AppSettings>(Configuration.GetSection("ConnectionStrings"));
    

    Для доступа к слою DAL аналогично вам нужно будет создать там класс AppSettings, а затем просто использовать

    public BaseDal(IOptions<AppSettings> app)
    {
        _connectionString = app.Value.MsSqlConnectionString;;
    }
    

    Изменить

    Когда вы получите

    Ошибка: не указан аргумент, соответствующий обязательному формальному параметру app в BaseDal.BaseDal (IOptions)

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

    public class MyDAL : BaseDal, IMyDAL
    {
        ILogger _log;
        public MyDAL(ILoggerFactory loggerFactory,IOptions<AppSettings> app):base(app)
        {
            _log = loggerFactory.CreateLogger("ChildDAL");
        }
    }
    
    23.04.2018
  • Я должен был упомянуть об этом раньше. У меня есть несколько дочерних классов, унаследованных от BaseDAL, поэтому, если я добавлю параметризованный конструктор, я получу кучу ошибок от дочерних классов для передачи этого параметра. Ошибка: не указан аргумент, соответствующий обязательному формальному параметру app в BaseDal.BaseDal (IOptions ‹AppSettings›). 23.04.2018
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..