在哪里放置使用(SqlConnection)

Where to put using(SqlConnection)

我正在创建一个框架来将插件添加到我的应用程序中。每个插件都必须实现一个抽象 class。然后将每个插件编译为 DLL,主应用程序可以通过 Directory.GetFiles(myPath, "*.dll")

找到它

这一切都很顺利,我可以在主应用程序中实例化我的插件并使用它们。每个插件基本上都是一个仪表板小部件,用户可以将其添加到他的仪表板以向他显示一些图形或图表。这意味着,每个插件都有一个计时器,并且在每个计时器事件上,它都会使用应用程序 SQL 数据库中的数据刷新图形。

所以我的问题是,我应该把 SqlConnection 放在哪里?我是创建一个 SqlConnection 并将其作为参数传递给每个插件,还是传递连接字符串并让每个插件创建自己的 SqlConnection

如果我将应用程序的 SqlConnection 传递给插件,那么我想这将涉及对插件内部连接的一些管理。我显然必须检查它是否打开,如果它的状态是 ConnectionState.FetchingConnectionState.Executing 我该怎么办?它只是看起来很笨重。

但另一方面,考虑到多个用户将成为 运行 应用程序,并且每个用户可能在其仪表板中选择了多个插件,因此加起来可能达到 SqlConnections 个。这是可取的吗?我是否应该考虑第三种选择,即插件将其查询提供给主机,主机将其与来自其他插件的其他查询排队,并在查询执行后 return 将结果集发送给插件?这样至少每个用户都只有一个 SqlConnection,不管他们选择了多少个插件。

老实说,最后一个选项对我来说似乎相当复杂,我不太确定我将如何实现它。如果有人能给我指出一篇解释类似内容的文章,我将不胜感激。

您不应该在不同的插件之间共享连接,而是在插件内创建一个,甚至为每个查询创建一个。这不会影响性能,它们被设计成那样使用。

SqlConnection and multithreading

就我个人而言,我建议将连接工厂传递给您的插件,并让它们创建和使用它们认为合适的连接。这意味着您的应用程序控制着连接字符串(尽管它们仍然可能从连接中读取它,除非您也将其抽象掉),但它们可以根据需要自由创建和使用连接。正如之前的回答所指出的,如果您只给他们一个连接,那么管理多线程问题以及您自己提到的共享问题需要做很多工作。

您可以做一些简单的事情:

public interface ISqlConnectionFactory
{
   SqlConnection GenerateConnection();
}

public class SqlConnectionFactory : ISqlConnectionFactory
{
   private readonly string _connectionString;

   public SqlConnectionFactory()
   {
      _connectionString = "your connection string here";
   }

   public SqlConnection GenerateConnection()
   {
       return new SqlConnection(_connectionString);
   }
}

然后插件负责管理连接(例如打开、关闭、处理)。您可以用它做更多的事情来对连接进行不同级别的控制,尝试检测行为不端的插件等。

编辑

当然,您的插件应该使用 using() 语句:

public void MyPluginMain(ISqlConnectionFactory factory)
{
   using(var connection = factory.GenerateConnection())
   {
      // Do the work
   }
}

请记住,您的应用正在将维护这些连接的责任转移给插件,插件 必须 在完成连接后清理连接,无论是由using() 语句,或者在完成它已经完成的操作后实际调用 Dispose()。如果这是任何类型的 'public' API,这应该是您文档的一部分。