Ввод строки подключения в класс DbContext с использованием Autofac в службе верхней полки (.Net Framework)

#c# #autofac #dbcontext #topshelf

#c# #autofac #dbcontext #верхняя полка

Вопрос:

Я создаю службу, которая, к сожалению, должна ссылаться на устаревшие библиотеки DLL для нашей ERP-системы.NET framework — это то, как мне нужно это сделать. Я пытался использовать службу Core Worker, но мои вызовы библиотек DLL не будут работать.

Мне нравится использовать TopShelf, и я искал DI для использования с этим, и Autofac, похоже, подходит, и у него есть поддержка TopShelf. Мне не нравится сохранять какие-либо настройки в наших файлах конфигурации, чтобы упростить развертывание в других средах. У нас есть целая система, которая сохраняет настройки, привязанные к среде, в которой вы находитесь (dev, test, prod и т. Д.). В основных приложениях я просто вводлю строку подключения при запуске, и все хорошо. В этом приложении я хочу вводить строку подключения при запуске службы и иметь возможность в любое время запускать класс DbContect и использовать эту строку подключения.

Поскольку я создаю свой слой данных и не хочу изменять сгенерированный DbContext, поэтому я создал другой частичный класс (MyContext.Custom.cs) с конструктором, который позволяет мне передавать строку подключения

  public MyContext(string name) : base(name)
    { }
  

В моем Program.cs я добавляю в контейнер Autofac на верхнюю полку

 HostFactory.Run(serviceConfig =>
    {
        serviceConfig.UseAutofacContainer(container);
        // etc...
    }
  

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

 static IContainer BuildContainer()
{
    string myConnectionString = AppConfig.Instance.Settings["MyConnectionString"];

    var builder = new ContainerBuilder();

    //builder.RegisterType<MyContext>()
    //    .UsingConstructor(typeof(string))
    //    .WithParameter("name", myConnectionString)
    //    .InstancePerLifetimeScope();

    //builder.Register(c => new MyContext(myConnectionString)).As<MyContext>();
    //.WithParameter("name", myConnectionString);

    //builder.RegisterType<MyContext>()
    //    .WithParameter("name", myConnectionString)
    //    .AsSelf();
    //.InstancePerLifetimeScope();

    builder.Register(c => new MyContext(myConnectionString)).AsSelf();

    builder.RegisterType<MainService>();
    return builder.Build();
}
  

Я пробовал каждый вариант с.Как и .AsSelf(). Я вставил .InstancePerLifetimeScope() и также пропустил его. Я не совсем уверен, на что устанавливать область видимости в этом случае, но решил, что это должно работать со временем жизни. Что бы я ни пробовал, я, похоже, не могу заставить его использовать мой конструктор.

Если я пропустил какую-либо информацию, не стесняйтесь спрашивать, и я могу ее заполнить. Надеюсь, кто-то это сделал. Я думаю, я мог бы передавать строку подключения каждый раз, когда я создаю экземпляр DbContext, но я надеялся заставить его работать как основное приложение, которое намного приятнее.

Спасибо

РЕДАКТИРОВАТЬ: добавление кода, чтобы показать, как я использую свой DbContext

 public bool Start()
{
    using(var db = new MyContext())
    {
        var warehouse = (from w in db.Warehouses
                         where w.WarehouseCode == "ABCD"
                         select w).FirstOrDefault(); 
    }
    // other code...
}
  

Комментарии:

1. Не могли бы вы показать нам пример класса (например MainService ), который зависит от DbContext? Тогда, возможно, мы сможем помочь определить проблему..

2. Я добавил этот код выше в функцию запуска моего MainService, поскольку обычное место, в которое я попадаю, моя база данных находится в другом проекте и имеет много уровней, чтобы добраться до нее. Я получаю ту же ошибку, что и при невозможности найти имя строки подключения в конфигурации. Также используется конструктор по умолчанию, а не мой пользовательский конструктор. Надеюсь, это поможет.

3. тьфу, думаю, я передаю свою строку подключения по цепочке, чувствую себя таким грязным.