Как добавить логику для выбора строки подключения, когда вызывается метод, а не вводить строку подключения в конструктор? - PullRequest
0 голосов
/ 04 декабря 2018

Название вопроса может вводить в заблуждение, чтобы дублировать, но мое требование другое.

Мое требование - инициализировать переменную перед каждым method вызовом.

//dummy code
Connection con;
public async Task<MyClass> GetDetails(int Id)
{
    con = new Connection("conString");
    //and after that other logic.....
}

Проблема:

  • Я не могу инициализировать variable в constructor, потому что conString не будет доступен, так как он использует DI и constructor, вызываемый ранее, то есть в Startup.cs.
  • Я не могу (не уверен, но предполагаю) для ActionFilters, потому что этот класс не мой Controller Class.
  • Или даже я иду на Filters, как инициализировать этопеременная, как я буду писать Filter в другом классе, и этого variable там не будет.
  • Или мне нужно написать одну строку code в каждом методе, который я пытаюсьчтобы избежать.

Здесь, как то, что я хочу, но не знаю, как это сделать.

Connection con;
[Filter/Attribute(con)]
public async Task<MyClass> GetDetails(int Id)
{
    //con should have initialized till here.
    //conString I can get where the Logic defined
    //and after that other logic.....
}

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

1 Ответ

0 голосов
/ 04 декабря 2018

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

Но хорошие новостиявляется то, что вы уже используете DI, что делает это проще.

Вместо внедрения строки подключения, введите фабрику, которая возвращает нужную строку подключения.

Это может быть либо интерфейс:

public interface IConnectionStringFactory
{
    string GetConnectionString();
}

или делегат:

public delegate string GetConnectionStringFunction();

Если есть какая-то информация, имеющаяся у метода, которая определяет, какая строка подключения будет использоваться, вы можете передать ее фабрике:

public interface IConnectionStringFactory
{
    string GetConnectionString(Something whatever);
}

Логика выбора строки подключения находится в реализации фабрики.

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

public class MyClass
{
    private readonly IConnectionStringFactory _connectionStringFactory;

    public MyClass(IConnectionStringFactory connectionStringFactory)
    {
        _connectionStringFactory = connectionStringFactory;
    }

    public async Task<MyClass> GetDetails(int Id)
    { 
        var connectionString = _connectionStringFactory.GetConnectionString();
        con = new Connection(connectionString);
        //and after that other logic.....
    }
}

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

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

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

...