Как изменить исходный каталог во время выполнения при использовании строки подключения и dapper - PullRequest
1 голос
/ 22 апреля 2020

Я пишу приложение MVC C#. Я использую Dapper в качестве легкого ORM. Мои строки подключения определены с помощью сервера и исходного каталога, и в настоящее время, если мне нужен доступ к другой базе данных, я определяю другую строку подключения и использую привязки Ninject, чтобы использовать конкретную строку подключения на основе менеджера, в который я внедряю ее, вот так :

public class NinjectBindings : NinjectModule
{
    public override void Load()
    {
        Bind<IDbConnection>().To<SqlConnection>()
           .WhenInjectedInto<DashboardManager>()
           .InRequestScope()
           .Named("myDashboard")
           .WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["dbDashboard"].ConnectionString);

        Bind<IDbConnection>().To<SqlConnection>()
           .WhenInjectedInto<ScoreboardManager>()
           .InRequestScope()
           .Named("myScoreboard")
           .WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["dbScoreboard"].ConnectionString);

    }
}

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

Вопрос: Могу ли я просто определить одну строку подключения, потерять все вышеперечисленные привязки и просто изменить «Исходный каталог» на точку на другую базу данных на лету?

1 Ответ

2 голосов
/ 23 апреля 2020

Нужны ли ограничения Named и WhenInjectedInto для ваших привязок?

Я полагаю, что у вас есть класс, который требует оба connectionstring s, это может быть достигнуто с помощью Named привязки:

Bind<IDbConnection>().To<SqlConnection>()
   .InRequestScope()
   .Named("myDashboard")
   .WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["dbDashboard"].ConnectionString);

Bind<IDbConnection>().To<SqlConnection>()
   .InRequestScope()
   .Named("myScoreboard")
   .WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["dbScoreboard"].ConnectionString);

И ваш класс может получить оба соединения:

public class ClassWith2DbDependency // <-- I would question this class for SRP violation
{
    private readonly IDbConnection _dashboardConnection;
    private readonly IDbConnection _scoreboardConnection;

    public ClassWith2DBDependency(
        [Named("myDashboard")] IDbConnection dashboardConnection
        [Named("myScoreboard")] IDbConnection scoreboardConnection)
    {
        _dashboardConnection = dashboardConnection;
        _scoreboardConnection = scoreboardConnection;
    }

    public void WriteTo2Dbs()
    {
        // execute dashboard DB procedure
        // execute scoreboard DB procedure
    }
}

Могу ли я просто определить одну строку подключения, потерять все вышеперечисленные связующие элементы и просто изменить исходный каталог на точку в другой базе данных на лету?

Изменение Initial Catalog не влияет на существующий SqlConnection. Можно управлять зависимостями самостоятельно, но вам все еще нужно 2 connectionstring с:

public class ClassWith2DbDependency
{
    public void WriteTo2Dbs()
    {
        var dashboardCon = ConfigurationManager.ConnectionStrings["dbDashboard"].ConnectionString;
        using (SqlConnection connection = new SqlConnection(dashboardCon))
        {
            // execute dashboard DB procedure
        }

        var scoreboardCon = ConfigurationManager.ConnectionStrings["dbScoreboard"].ConnectionString;
        using (SqlConnection connection = new SqlConnection(scoreboardCon))
        {
            // execute scoreboard DB procedure
        }
    }
}

Однако я НЕ рекомендую этот подход, приведенный выше класс нарушает Принцип DI, при наличии непрозрачных зависимостей .


Я не видел ваш код, но не похоже, что вы используете Repository Pattern ? Это может быть хорошим вариантом ...

...