I'd like to know your opinion on a matter of coding style that I'm on the fence about. I realize there probably isn't a definitive answer, but I'd like to see if there is a strong preference in one direction or the other.
I'm going through a solution adding using statements in quite a few places. Often I will come across something like so:
{
log = new log();
log.SomeProperty = something; // several of these
log.Connection = new OracleConnection("...");
log.InsertData(); // this is where log.Connection will be used
... // do other stuff with log, but connection won't be used again
}
where log.Connection is an OracleConnection, which implements IDisposable.
The neatnik in me wants to change it to:
{
using (OracleConnection connection = new OracleConnection("..."))
{
log = new log();
log.SomeProperty = something;
log.Connection = conn;
log.InsertData();
...
}
}
But the lover of brevity and getting-the-job-done-slightly-faster wants to do:
{
log = new log();
log.SomeProperty = something;
using (log.Connection = new OracleConnection("..."))
log.InsertData();
...
}
For some reason I feel a bit dirty doing this. Do you consider this bad or not? If you think this is bad, why? If it's good, why?
EDIT: Please note that this is just one (somewhat contrived) example of many. Please don't fixate on the fact that this happens to indicate a logger class with a poorly thought-out interface. This is not relevant to my question, and I'm not at liberty to improve the classes themselves anyway.
They are both horrid. Do neither of them.
You're making what I call a "high maintenance class" here. The high maintenance class has a contract that says "I require you to give me a bunch of resources, and you're required to know when I'm done with them and clean them up appropriately". This contract means that the user of the class has to know how the class is implemented, thereby violating the principle of encapsulation and abstraction that motivated making a class in the first place.
You can tell this by your comment: this is where the connection is used, I know the connection will not be used again. How do you know that? You only know that if that is the documented contract of the class. That's not a good contract to impose upon the consumer of a class.
Some ways to make this better:
1) make the logger disposable. Have it clean up the connection when it is done. The down side of this is that the logger holds on to the connection for longer than necessary.
2) make InsertData take the connection as a parameter. The caller can still be responsible for cleaning up the connection because the logger does not hold onto it.
3) make a third class "Inserter" which is disposable and takes a log and a connection in its constructor. The inserter disposes of the connection when it is disposed; the caller then is responsible for disposing the inserter.
I agree that ideally log itself should implement IDisposable, but let's assume that's not possible and address the question the OP actually asked.
The second way is better, simply because it's less code that accomplishes the same thing. There is no advantage to introducing an additional connection variable here.
Also note that you could do other initialisation outside of the using block. It won't matter here, but may matter if you're "using" some really expensive resource. That is:
log = new log();
log.SomeProperty = something; // This can be outside the "using"
using (OracleConnection connection = new OracleConnection("..."))
{
log.Connection = conn;
log.InsertData();
...
}
I would listen to the neatnik in you. I like his way better personally.
The two ways of using using are totally equivalent. Either way, you end up with a log that's still in scope but has a disposed connection. It's way better to make the log disposable and have its dispose method dispose of its connection, putting the log in the using statement, not the connection itself.
If log implements IDisposable, then do the second choice, as the braces are explicit. In some cases you can use multiple using statements:
using (Graphics g = ...)
using (Pen p = new Pen ...)
using (Font f = new Font ...)
{
}
where you can get away with only using 1 set of braces. This avoids crazy indents.
Related
Sometimes I see people like to dispose just anything after use regardless of how frequently they're being used (probably not related to SQLite question, but I am dealing with SQLite as of now, I'm puzzled) -- or perhaps I am mistaken. This has caused a massive confusion for me.
For example (taken from elsewhere):
using(var con = new SQLiteConnection(conString))
using(var cmd = new SQLiteCommand(con))
{
con.Open();
// ...
} // also closes the connection
My question is, should I store the SQLiteConnection and SQLiteCommand objects in the field, and use the method .Open(), .Close() to handle the database connection without disposing them at all until application termination -- or dispose them into the Garbage Collection like it's not really an elegant idea in my perspective?
Edit: If one says dispose, then why? I need better answers, I need the true reason why, not because of pooling, and whatnot. I need to know what exact problems could arise other than human-prone errors, and provide an example or perhaps a link to the example.
For example the class field:
private static SQLiteConnection sQLiteConnection; /// <summary>SQLiteConnection.</summary>
public static SQLiteConnection SQLiteConnection { get { return sQLiteConnection; } }
private static SQLiteCommand sQLiteCommand; /// <summary>SQLiteCommand.</summary>
public static SQLiteCommand SQLiteCommand { get { return sQLiteCommand; } }
Where the private fields are initialized with a private method, and the objects are to be reused without disposing them; Hence the read-only properties.
Edit 2: For clearer clarification, are you people misreading? I am saying "reusing". Which means one is created, and stored somewhere in the field to be reused. I am storing it in the static field in a static class to be reused until the application is closed. Tell me, why do I have to dispose it?
Why, do, I, have, to, dispose, it? If, I, were, to, "reuse", it? Why?
Connections are pooled by .NET, so creating them generally isn't an expensive operation. Using the "standard" approach is generally much cleaner that trying to keep track of if a connection is open or closed, etc.
Unless you have measurable problems with connection I would stick with the idomatic approach of creating them, using them, and disposing of them.
The msdn documentation of the System.IDisposable interface states that
The primary use of this interface is to release unmanaged resources.
I'm wondering what are alternative uses.
For example we also needed the IDisposable interface for other allocated resources, such as event subscription and so.
We used the interface as a marker to allow a class instance to know when it's no more used from clients. Client and infrastructural code explicitly call IDisposable.Dispose() whenever they no more need a logical instance of a class implementing the code.
There's no relation with unmanaged resources wrapped from the interface.
When we choosed the IDisposable interface for such a behaviour we considered it as an alternative (undocumented) use of the interface.
Which are the alternative use of IDisposable you have found?
Are they legittimate? Is the MSDN documentation wrong?
I think your reading of the documentation is wrong. Saying that any usage of IDisposable that is not related to unmanaged resources is undocumented is a bit like saying that any usage of System.Int32 that is not counting things is undocumented. It is an interface and has no implementation, there is no functionality there to even begin distinguishing between what's documented and what's undocumented.
The purpose of IDisposable is simply to provide the developer with a mechanism to deterministically control the lifetime of their objects. It just so happens that this mainly a requirement for dealing with unmanaged resources.
One of the more fancy uses of IDisposable is the using block syntactic sugar. As others have mentioned, using blocks give an operation scope and I think those are quite elegant.
Example 1 - timing blocks
StackOverflow uses mini profiler that uses using blocks to identify nested regions of execution:
using (profiler.Step("Doing complex stuff"))
{
using (profiler.Step("Step A"))
{ // something more interesting here
Thread.Sleep(100);
}
using (profiler.Step("Step B"))
{ // and here
Thread.Sleep(250);
}
}
The alternative to not using using is pretty horrible and I don't even want to mock it up here.
Example 2 - Disposable action
There have been different variations of disposable action pattern making rounds in .NET Domain Driven Design circles. Ayende has one, so does Udi Dahan in his Domain Events implementation, Jimmmy Bogard has a slightly different take on this, still in the context of Domain Events. The crux of the pattern is that you want to perform certain actions in some context, then have the context revert back to what it was before after you are done.
Ayende provides a simple example:
class UsuallyReadOnly {
//.. implementation
public IDisposable AllowModification
{
get
{
_allowModification = true;
return new DisposableAction(()=>{ _allowModification = false; } );
}
}
}
And UsuallyReadOnly's usage:
UsuallyReadOnly foo = new UsuallyReadOnly();
using(foo.AllowModification)
{
foo.Name = "Bar";
}
IDisposable is often used in conjunction with using to activate and deactivate something in a definite scope even if it is not an unmanaged resource. The use you describes sound as a reference counting and for sure is not recommended.
For "resources", substitute "responsibilities". When an object is said to hold an unmanaged resource, what that really means is that there is some task that needs to get done sometime, and the object is the only thing with the information and impetus necessary to do it. The purpose of "Dispose" isn't to get rid of any tangible entity, but rather to allow an object to "put its affairs in order". Someone is putting his affairs in order before his death isn't doing anything to himself, but rather he is ensuring that the things he has to do to persons and things outside himself get done. Likewise with IDisposable.Dispose.
Remember there is also the using pattern which acts a bit like RAII.
using ( DisposableObject obj = new DisposableObject( ) )
{
.....
}
So Dispose gets called when the using block is exited.
One of the more popular uses of the IDisposable interface is transaction scopes. You can use it to wrap some SQL logic in a transaction, and explicitly call Complete() to end the transaction:
using (var scope = new TransactionScope())
{
using (var connection = new SqlConnection(connectString))
{
// perform sql logic
...
scope.Complete();
}
}
You could also use a similar pattern for just about anything that requires a temporary function, such as creating and deleting a temporary file:
public class TempFileProvider : IDisposable
{
public Filename { get; private set; }
public TempFileProvider()
{
Filename = Path.GetTempFileName();
}
public void Dispose()
{
File.Delete(Filename);
}
}
So you could use it like:
using (var tempFileProvider = new TempFileProvider())
{
DoSomethingWithFile(tempFileProvider.Filename);
} // deletes temp file
Have a look at the following question Need an alternative to my IDisposable Hack
There i give a nice example of what i used IDisposable for. :)
Granted, it is not the ideal solution, however, it helped me a lot.
In my current production code, and according to documentation on msdn, the way to create a client is this
using (WebChannelFactory<IServiceInterface> cf
= new WebChannelFactory<IServiceInterface>("http://service.url"))
{
IServiceInterface client = cf.CreateChannel();
client.CallTheMethod();
}
given that I have this interface:
public interface IServiceInterface
{
void CallTheMethod();
}
However I noticed that the object client created by the WebChannelFactory also implements IDisposable. So I want to dispose this object also. I didn't find any other way than:
using (WebChannelFactory<IServiceInterface> cf
= new WebChannelFactory<IServiceInterface>("http://service.url"))
using(IDisposable client = (IDisposable)cf.CreateChannel())
{
((IServiceInterface)client).CallTheMethod();
}
I find this ugly. So :
Do I really need to dispose it ? I mean that may be it is disposed when you disposed the factory (if the factory keeps a reference to every object it has created maybe) ?
If yes, do you have a better way ?
This is a very complex issue. Even by Microsoft's own admission, disposing of channel factories was a bad design which was changed multiple times so short answer is no, you need to use something alternative to it.
Here is an alternative method to disposing.
I sometimes use braces to isolate a block of code to avoid using by mistake a variable later. For example, when I put several SqlCommands in the same method, I frequently copy-paste blocks of code, ending by mixing the names and executing twice some commands. Adding braces helps to avoid this situation, because using a wrong SqlCommand in a wrong place will result in an error. Here's an illustration:
Collection<string> existingCategories = new Collection<string>();
// Here a beginning of a block
{
SqlCommand getCategories = new SqlCommand("select Title from Movie.Category where SourceId = #sourceId", sqlConnection, sqlTransaction);
getCategories.Parameters.AddWithValue("#sourceId", sourceId);
using (SqlDataReader categoriesReader = getCategories.ExecuteReader(System.Data.CommandBehavior.SingleResult))
{
while (categoriesReader.Read())
{
existingCategories.Add(categoriesReader["Title"].ToString());
}
}
}
if (!existingCategories.Contains(newCategory))
{
SqlCommand addCategory = new SqlCommand("insert into Movie.Category (SourceId, Title) values (#sourceId, #title)", sqlConnection, sqlTransaction);
// Now try to make a mistake and write/copy-paste getCategories instead of addCategory. It will not compile.
addCategory.Parameters.AddWithValue("#sourceId", sourceId);
addCategory.Parameters.AddWithValue("#title", newCategory);
addCategory.ExecuteNonQuery();
}
Now, StyleCop displays a warning every time a block follows an empty line. On the other hand, not putting an empty line would make the code much harder to understand.
// Something like:
Collection<string> existingCategories = new Collection<string>();
{
// Code here
}
// can be understood as (is it easy to notice that semicolon is missing?):
Collection<string> existingCategories = new Collection<string>()
{
// Code here
}
So,
Is there something wrong in using braces to create blocks of code just for variable scope purposes?
If it's all right, how to make it more readable without violating StyleCop rules?
There's nothing wrong per se with blocking off code, but you need to consider why you're doing it.
If you're copying and pasting code, you're likely in a situation where you should be refactoring the code and producing functions that you call repeatedly rather than executing similar but different blocks of code repeatedly.
Use the using statement instead of bare brace blocks.
This will avoid the warnings, and also make your code more efficient in terms of resources.
From a larger perspective, you should consider splitting up this method into smaller methods. Using one SqlCommand followed by another is usually better done by calling one method followed by another. Each method would then use their own local SqlCommand.
I don't think there's anything wrong with using braces purely to delimit scope - it can be quite useful at times.
Case in point - I came across a profiling library once that used Profile objects to time sections of code. These worked by measuring the time from their creation to destruction, and therefore worked best by being created on the stack and then being destroyed when they went out of scope, thus measuring the time spent in that particular scope. If you wanted to time something that didn't inherently have its own scope, then adding extra braces to define that scope was probably the best way to go.
As for readability, I can understand why StyleCop doesn't like it, but anyone with any experience in C/C++/Java/C#/... knows that a brace pair defines a scope, and it should be fairly evident that that's what you're trying to do.
I think such blocks is good idea, I'm using their often. It is useful when you need to separate blocks of code that are too small to be extracted into method, or when method consists of few code blocks looks like each other, but not with the same logic. It allows to give variables the same names without naming conflicts, and this makes method body more readable.
By the way, my opinion StyleCop has default rule set with more rules which expediency is debatable.
I'd have to say if I were to work on this code after you I'd be a little offput by your use of scope. Its not, afaik, common practice.
I'd consider it a smell that you'd be doing this. I would think the better practice would be to break off each scope into its own method with fully descriptive names and documentation.
I have a method that I want to be "transactional" in the abstract sense. It calls two methods that happen to do stuff with the database, but this method doesn't know that.
public void DoOperation()
{
using (var tx = new TransactionScope())
{
Method1();
Method2();
tc.Complete();
}
}
public void Method1()
{
using (var connection = new DbConnectionScope())
{
// Write some data here
}
}
public void Method2()
{
using (var connection = new DbConnectionScope())
{
// Update some data here
}
}
Because in real terms the TransactionScope means that a database transaction will be used, we have an issue where it could well be promoted to a Distributed Transaction, if we get two different connections from the pool.
I could fix this by wrapping the DoOperation() method in a ConnectionScope:
public void DoOperation()
{
using (var tx = new TransactionScope())
using (var connection = new DbConnectionScope())
{
Method1();
Method2();
tc.Complete();
}
}
I made DbConnectionScope myself for just such a purpose, so that I don't have to pass connection objects to sub-methods (this is more contrived example than my real issue). I got the idea from this article: http://msdn.microsoft.com/en-us/magazine/cc300805.aspx
However I don't like this workaround as it means DoOperation now has knowledge that the methods it's calling may use a connection (and possibly a different connection each). How could I refactor this to resolve the issue?
One idea I'm thinking of is creating a more general OperationScope, so that when teamed up with a custom Castle Windsor lifestyle I'll write, will mean any component requested of the container with OperationScopeLifetyle will always get the same instance of that component. This does solve the problem because OperationScope is more ambiguous than DbConnectionScope.
I'm seeing conflicting requirements here.
On the one hand, you don't want DoOperation to have any awareness of the fact that a database connection is being used for its sub-operations.
On the other hand, it clearly is aware of this fact because it uses a TransactionScope.
I can sort of understand what you're getting at when you say you want it to be transactional in the abstract sense, but my take on this is that it's virtually impossible (no, scratch that - completely impossible) to describe a transaction in such abstract terms. Let's just say you have a class like this:
class ConvolutedBusinessLogic
{
public void Splork(MyWidget widget)
{
if (widget.Validate())
{
widgetRepository.Save(widget);
widget.LastSaved = DateTime.Now;
OnSaved(new WidgetSavedEventArgs(widget));
}
else
{
Log.Error("Could not save MyWidget due to a validation error.");
SendEmailAlert(new WidgetValidationAlert(widget));
}
}
}
This class is doing at least two things that probably can't be rolled back (setting the property of a class and executing an event handler, which might for example cascade-update some controls on a form), and at least two more things that definitely can't be rolled back (appending to a log file somewhere and sending out an e-mail alert).
Perhaps this seems like a contrived example, but that is actually my point; you can't treat a TransactionScope as a "black box". The scope is in fact a dependency like any other; TransactionScope just provides a convenient abstraction for a unit of work that may not always be appropriate because it doesn't actually wrap a database connection and can't predict the future. In particular, it's normally not appropriate when a single logical operation needs to span more than one database connection, whether those connections are to the same database or different ones. It tries to handle this case of course, but as you've already learned, the result is sub-optimal.
The way I see it, you have a few different options:
Make explicit the fact that Method1 and Method2 require a connection by having them take a connection parameter, or by refactoring them into a class that takes a connection dependency (constructor or property). This way, the connection becomes part of the contract, so Method1 no longer knows too much - it knows exactly what it's supposed to know according to the design.
Accept that your DoOperation method does have an awareness of what Method1 and Method2 do. In fact, there is nothing wrong with this! It's true that you don't want to be relying on implementation details of some future call, but forward dependencies in the abstraction are generally considered OK; it's reverse dependencies you need to be concerned about, like when some class deep in the domain model tries to update a UI control that it has no business knowing about in the first place.
Use a more robust Unit of Work pattern (also: here). This is getting to be more popular and it is, by and large, the direction Microsoft has gone in with Linq to SQL and EF (the DataContext/ObjectContext are basically UOW implementations). This sleeves in well with a DI framework and essentially relieves you of the need to worry about when transactions start and end and how the data access has to occur (the term is "persistence ignorance"). This would probably require significant rework of your design, but pound for pound it's going to be the easiest to maintain long-term.
Hope one of those helps you.