Today I noticed a snippet of code that looks like the one below:
public class Test
{
SqlConnection connection1 =
new SqlConnection(ConfigurationManager.ConnectionStrings["c1"].ToString());
SqlConnection connection2 =
new SqlConnection(ConfigurationManager.ConnectionStrings["c2"].ToString());
public void Method1()
{
using (connection1)
{
connection1.Open();
using (SqlCommand newSqlCommand = new SqlCommand("text",connection2))
{
// do something
}
}
}
public void Method2()
{
using (connection1)
{
// do something
}
}
}
I am just wondering why would anyone want to open the connection when creating the class and not when calling the corresponding methods inside the class?
EDIT: I should have probably posted the whole code instead. So I do see where they are opening connection1, but then they are instantiating a sqlcommand with a different sql connection (connection2) which has not been opened anywhere. What am I missing here?
Thanks,
This line only initializes a connection object, which can later be used to open a connection to a database server.
SqlConnection connection1 =
new SqlConnection(ConfigurationManager.ConnectionStrings["c1"].ToString());
What I know is that using disposes of an object (and in the case of Connection objects they are automatically closed) after its scope so I wouldn't recommend such usage because it might be problematic with other object types (other than Connection) that can't be used after having their dispose called.
connection1 = new SqlConnection(...) does not really open the connection. It just creates the connection object.
You have to call connection1.Open(); to actually open it. You can do this inside using statement block.
Refer to this MSDN page for more details.
It either
written this way to enforce only single call to a method be performed on the class
unintentionally confusing by throwing ObjectDisposed exception if you call 2 methods
contains connection re-initialization code in blocks you've ommited.
The code is dangerous.
If you call Method1 then Method2 (or visa versa) you will get an error (connection string not initialized).
The error occurs because the using statement will close the connection AND Disposes the object. I double checked what happens when dispose is called...the connection string is cleared (and possibly some other things I didn't notice).
You don't want to re-use a disposed object.
The cost of instantiating a new connection object is insignificant so I would just create the object where needed, maybe with a little factory method to reduce code duplication, so change to something like:-
private static SqlConnection GetSqlConnection()
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["c1"].ToString());
}
private void Method1()
{
using (var conn = GetSqlConnection())
{
conn.Open();
// do stuff...
}
}
private void Method2()
{
using (var conn = GetSqlConnection())
{
conn.Open();
// do other stuff...
}
}
Of course there are many different ways of approaching this problem, this is just one and indeed quite a simplistic one...but it is a good starting point and is safe :-)
Related
I am writing SQL Server integration tests using xUnit.
My tests look like this:
[Fact]
public void Test()
{
using (IDbConnection connection = new SqlConnection(_connectionString))
{
connection.Open();
connection.Query(#$"...");
//DO SOMETHING
}
}
Since I am planning to create multiple tests in the same class I was trying to avoid creating a new SqlConnection every time. I know that xUnit framework per se creates an instance of the class per each running test inside it.
This means I could make the creation of the SqlConnection in the constructor since anyway a new one will be created every time a new test run.
The problem is disposing it. Is it good practice or do you see any problem in disposing manually the SqlConnection at the end of each test?
Such as:
public class MyTestClass
{
private const string _connectionString = "...";
private readonly IDbConnection _connection;
public MyTestClass()
{
_connection = new SqlConnection(_connectionString));
}
[Fact]
public void Test()
{
_connection.Open();
_connection.Query(#$"...");
//DO SOMETHING
_connection.Dispose();
}
}
I was trying to avoid creating a new SqlConnection every time.
It's okay to create and dispose a new SqlConnection over and over. The connection instance is disposed, but the underlying connection is pooled. Under the hood it may actually use the same connection repeatedly without closing it, and that's okay.
See SQL Server Connection Pooling.
So if that's your concern, don't worry. What you are doing in the first example is completely harmless. And however your code is structured, if you're creating a new connection when you need it, using it, and disposing it, that's fine. You can do that all day long.
If what concerns you is the repetitive code, I find this helpful. I often have a class like this in my unit tests:
static class SqlExecution
{
public static void ExecuteSql(string sql)
{
using (var connection = new SqlConnection(GetConnectionString()))
{
using (var command = new SqlCommand(sql, connection))
{
connection.Open();
command.ExecuteNonQuery();
}
}
}
public static T ExecuteScalar<T>(string sql)
{
using (var connection = new SqlConnection(GetConnectionString()))
{
using (var command = new SqlCommand(sql, connection))
{
connection.Open();
return (T)command.ExecuteScalar();
}
}
}
public static string GetConnectionString()
{
// This may vary
}
}
How you obtain the connection string may vary, which is why I left that method empty. It might be a configuration file, or it could be hard-coded.
This covers the common scenarios of executing something and retrieving a value, and allows me to keep all the repetitive database code out of my tests. Within the test is just one line:
SqlExecution.ExecuteSql("UPDATE WHATEVER");
You can also use dependency injection with xUnit, so you could write something as an instance class and inject it. But I doubt that it's worth the effort.
If I find myself writing more and more repetitive code then I might add test-specific methods. For example the test class might have a method that executes a certain stored procedure or formats arguments into a query and executes it.
You can also do dependency injection with xUnit so that dependencies are injected into the class like with any other class. There are lots of answers about this. You may find it useful. Maybe it's the reason why you're using xUnit. But something simpler might get the job done.
Someone is bound to say that unit tests shouldn't talk to the database. And they're mostly right. But it doesn't matter. Sometimes we have to do it anyway. Maybe the code we need
to unit test is a stored procedure, and executing it from a unit test and verifying the
results is the simplest way to do that.
Someone else might say that we shouldn't have logic in the database that needs testing, and I agree with them too. But we don't always have that choice. If I have to put logic in SQL I still want to test it, and writing a unit test is usually the easiest way. (We can call it an "integration test" if it makes anyone happy.)
There's a couple different things at play here. First, SqlConnection uses connection pooling so it should be fine to create/dispose the connections within a single test.
Having said that disposing of the connections on a per test class basis would also be doable. XUnit will dispose of test classes that are IDisposable. So either would work. I'd suggest it's cleaner to create/dispose them within the test.
public class MyTestClass : IDisposable
{
const string ConnectionStr = "";
SqlConnection conn;
public MyTestClass()
{
this.conn = new SqlConnection(ConnectionStr);
}
public void Dispose()
{
this.conn?.Dispose();
this.conn = null;
}
public void Test()
{
using (var conn = new SqlConnection(ConnectionStr))
{
}
}
}
I want to execute methods within a Sql Connection. I want to use the C# "using" object since it makes the connection safe.
The reason I want to execute queries in this way is so I can reuse this connection and build the queries in a separate class/location.
class foo
{
public void connectionMethod()
{
using(SqlConnection aConnection=new SqlConnection('ConnectionString')
{
//Query here.
}
}
}
Thanks for your help!
In the class you where you want to build your queries, declare each method to accept a SqlConnection parameter.
// query method
public void SomeQuery(SqlConnection connection)
{
...
}
// use it
using(SqlConnection aConnection=new SqlConnection('ConnectionString')
{
aConnection.Open();
otherClass.SomeQuery(aConnection);
}
Passing a parameter will create a copy of the reference to the SqlConnection object which will be in scope within the called method. Make sure you don't leak it outside the method though.
Such as so: Creating it in a method and assigning it to a field. Passing that field to a method and then assigning it to a variable of a using-statement (Which is the only Dispose being called).
SqlCommand CreateSqlCommand()
{
SqlCommand cmd1 = new SqlCommand();
return cmd1;
}
void UseSqlCommand(SqlCommand cmd4)
{
using (SqlCommand cmd3 = cmd4)//Is this using-statement enough?
{
//use cmd3 here...
}
}
And used:
SqlCommand cmd2 = CreateSqlCommand();
UseSqlCommand(cmd2);
Extra detail: Will the GC collect all of these variables on its next round or not? Why not - see David M. Kean's answer here.
EDIT
I've added
cmd2.CommandText = "";
after the previous (last) line. And there's no error thrown.
Why? It should be disposed already! Never mind. A disposed object can be referenced...
Please do not concentrate on the example, rather do - on the question itself. Thanks.
Yes, the using statement will call Dispose() after the block has completed on the referenced variable. This is a good and bad thing, suppose that you create a sql command and store the result in a variable cmd, then you pass that variable to another method that uses and disposes cmd. Now you are stuck with a variable that is disposed, and if you try to use it, it might throw an ObjectDisposedException.
SqlCommand cmd = CreateSqlCommand();
UseSqlCommand(cmd);
//Uh oh, cmd can still be used, what if I tried to call UseSqlCommand(cmd) again?
It would be more clear and secure to dispose of that object outside of the method(Like Jordão posted).
using(SqlCommand cmd = CreateSqlCommand())
{
UseSqlCommand(cmd);
}
Now you completely control the object and limit it's scope.
Control the scope of using from outside:
using (SqlCommand cmd2 = CreateSqlCommand()) {
UseSqlCommand(cmd2);
}
...
void UseSqlCommand(SqlCommand cmd4) {
// use cmd4 here...
}
And maybe rename UseSqlCommand to something different, like ExecuteSqlCommand.
The purpose of the using statement is not to dispose of variables, but rather object instances. Variables are often used for the purpose of identifying object instances, but reference-type variables don't hold object--they hold "object identifiers".
If one says e.g. var myPort = new System.Io.Ports.SerialPort("COM1", ...); myPort.Open(), the SerialPort object will ask the system to let it use the COM1 serial port and not let anyone else use it until further notice. The system will generate a handle for that port, and set some flags so that only code which has that handle will be allowed to use the port. Once the object is created (say the system arbitrarily assigns it an ID of #8675309), the system will store that ID into the variable myPort).
When code no longer needs to use that serial port, it is important that someone tell object #8675309 that it is no longer needed, so it can in turn tell the system that it should make COM1 available to other applications. This would typically be done by calling Dispose on a variable which holds a reference to object #8675309. Once that is done, every variable that holds a reference to object #8675309 will hold a reference to an object whose Dispose method has been called. Note that the Dispose method won't actually affect any of those variables (unless they are rewritten within the code of the method itself). Any variables which held "object #8675309" before the call will continue to do so after. The object will have released its serial port, so the reference which is stored those variables will no longer be useful for much, and the code that uses those variables may want them to be cleared, but the SerialPort object won't care one way or the other.
I think this is what you're trying to do:
public class MySqlClass : IDisposable
{
private SqlConnection conn { get; set; }
public MySqlClass(string connectionstring)
{
conn = new SqlConnection(connectionstring);
}
public void DoSomething1(string tsql)
{
using (SqlCommand comm = new SqlCommand(tsql, conn)) {
conn.Open();
}
}
public void DoSomething2(string tsql)
{
using (SqlCommand comm = new SqlCommand(tsql, conn)) {
conn.Open();
}
}
//DISPOSE STUFF HERE
}
Use...
using (MySqlClass MySQL = new MySqlClass())
{
MySQL.DoSomething1();
MySQL.DoSomething2();
}
* UPDATE *
Updated >>>> EXAMPLE <<<<< Point is you create single instance of SqlConnection above, and you can resuse it. The class implements IDisposable so you can use the using() method to auto dispose. Better than passing instances of SqlCommand like you mentioned.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
in a “using” block is a SqlConnection closed on return or exception?
Would this using close this _connection?
using(SqlConnection _connection = Class1.GetSqlConnection())
{ //code inside the connection
}
//connection should be closed/ended?
I'm just wondering because GetSqlConnection() is a static function of Class1 and the whole connection might not be closed because it is calling outside class' static function instead of straight?
using(SqlConnection _connection = new SqlConnection(_connectionString)
{ //code inside the connection
}
The using statement does not care how the variable gets its value, - be it from a static function, a member function, a new operator, or any other way. As soon as the closing brace of the using is reached, the Dispose() method on the variable will be called, closing the connection if it's an IDbConnection instance, or doing whatever else the IDisposable is to do upon disposing.
Yes it does.
Here is an alternative way to implement the GetSqlFunction method so that you have a more explicit behaviour:
public class Class1
{
private static SqlConnection GetSqlConnection() { /* unchanged */ }
public static void UseSqlConnection(Action<SqlConnection> action)
{
using (var connection = Class1.GetSqlConnection())
{
action(connection);
}
}
}
Then you call it like so:
Class1.UseSqlConnection(c =>
{
/* use connection here */
});
You could then extend this method to use an existing connection or create a new one depending on the semantics you prefer.
Yes, by design.
A using block is used to handle disposing of, well, disposable objects when the block ends. To Dispose() an object means to release all of the resources for that object. For objects such as SqlConnection, this will close their connection.
Most of the examples of the using statement in C# declare the object inside the brackets like this:
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Customers", connection))
{
// Code goes here
}
What happens if I use the using statement in the following way with the object declared outside the using statement:
SqlCommand cmd = new SqlCommand("SELECT * FROM Customers", connection);
using (cmd)
{
// Code goes here
}
Is it a bad idea to use the using statement in the way I have in the second example and why?
Declaring the variable inside the using statement's control expression limits the scope of the variable to inside the using statement. In your second example the variable cmd can continue to be used after the using statement (when it will have been disposed).
Generally it is recommended to only use a variable for one purpose, limiting its scope allows another command with the same name later in scope (maybe in another using expression). Perhaps more importantly it tells a reader of your code (and maintenance takes more effort than initial writing) that cmd is not used beyond the using statement: your code is a little bit more understandable.
Yes, that is valid - the object will still be disposed in the same manner, ie, at the end and if execution flow tries to leave the block (return / exception).
However if you try to use it again after the using, it will have been disposed, so you cannot know if that instance is safe to continue using as dispose doesn't have to reset the object state. Also if an exception occurs during construction, it will not have hit the using block.
I'd declare and initialize the variable inside the statement to define its scope. Chances are very good you won't need it outside the scope if you are using a using anyway.
MemoryStream ms = new MemoryStream(); // Initialisation not compiled into the using.
using (ms) { }
int i = ms.ReadByte(); // Will fail on closed stream.
Below is valid, but somewhat unnecessary in most cases:
MemoryStream ms = null;
using (ms = new MemoryStream())
{ }
// Do not continue to use ms unless re-initializing.
I wrote a little code along with some unit tests. I like it when I can validate statements about the question at hand. My findings:
Whether an object is created before or in the using statement doesn't matter. It must implement IDisposable and Dispose() will be called upon leaving the using statement block (closing brace).
If the constructor throws an exception when invoked in the using statement Dispose() will not be invoked. This is reasonable as the object has not been successfully constructed when an exception is thrown in the constructor. Therefore no instance exists at that point and calling instance members (non-static members) on the object doesn't make sense. This includes Dispose().
To reproduce my findings, please refer to the source code below.
So bottom line you can - as pointed out by others - instantiate an object ahead of the using statement and then use it inside the using statement. I also agree, however, moving the construction outside the using statement leads to code that is less readable.
One more item that you may want to be aware of is the fact that some classes can throw an exception in the Dispose() implementation. Although the guideline is not to do that, even Microsoft has cases of this, e.g. as discussed here.
So here is my source code include a (lengthy) test:
public class Bar : IDisposable {
public Bar() {
DisposeCalled = false;
}
public void Blah() {
if (DisposeCalled) {
// object was disposed you shouldn't use it anymore
throw new ObjectDisposedException("Object was already disposed.");
}
}
public void Dispose() {
// give back / free up resources that were used by the Bar object
DisposeCalled = true;
}
public bool DisposeCalled { get; private set; }
}
public class ConstructorThrows : IDisposable {
public ConstructorThrows(int argument) {
throw new ArgumentException("argument");
}
public void Dispose() {
Log.Info("Constructor.Dispose() called.");
}
}
[Test]
public void Foo() {
var bar = new Bar();
using (bar) {
bar.Blah(); // ok to call
}// Upon hitting this closing brace Dispose() will be invoked on bar.
try {
bar.Blah(); // Throws ObjectDisposedException
Assert.Fail();
}
catch(ObjectDisposedException) {
// This exception is expected here
}
using (bar = new Bar()) { // can reuse the variable, though
bar.Blah(); // Fine to call as this is a second instance.
}
// The following code demonstrates that Dispose() won't be called if
// the constructor throws an exception:
using (var throws = new ConstructorThrows(35)) {
}
}
The idea behind using is to define a scope, outside of which an object or objects will be disposed.
If you declare the object you are about to use inside using in advance, there's no point to use the using statement at all.
It has been answered and the answer is: Yes, it's possible.However, from a programmers viewpoint, don't do it! It will confuse any programmer who will be working on this code and who doesn't expect such a construction. Basically, if you give the code to someone else to work on, that other person could end up being very confused if they use the "cmd" variable after the using. This becomes even worse if there's even more lines of code between the creation of the object and the "using" part.