Disposing client after creation with WebChannelFactory - c#

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.

Related

Should we still create instances if we want to take advantage of dependency injection?

I am getting deeper into the Dependency Injection concept and more I read, more I like the idea behind it. I have been using it for some time already, but still many things confuse me every now and then, and I feel that I am not using its full potential.
Imagine the code below. In this class, (probably a few things can be improved but..) we have one method that returns a string value. There is no need for constructor injection (or at least that's what I think, correct me if I am wrong), but then at the last line in the try block, we create new instance of the StreamReader class to be able to pass the response stream to it and to get the result using the ReadToEnd method.
The idea behind Dependency Injection is to avoid creating instances inside a class, but how to deal with this scenario?
public class WebClientService : IWebClientService
{
public async Task<String> GetApiResponseAsync(string Url)
{
String responseText = await Task.Run(() =>
{
try
{
HttpWebRequest request = WebRequest.Create(Url) as HttpWebRequest;
WebResponse response = request.GetResponse();
Stream responseStream = response.GetResponseStream();
return new StreamReader(responseStream).ReadToEnd();
}
catch (Exception e)
{
LogMessageDispatcher.Instance.Log(e);
}
return null;
});
return responseText;
}
}
I am going over 'Mark Seemann's book - Dependency Injection', but I still have a lot to cover.
This is a very trivial example and relatively easy to define as your coupling is a basic Class without any service related functionality. Let's start from the definition of DI in wikipedia:
In software engineering, dependency injection is a technique whereby one object supplies the dependencies of another object. A "dependency" is an object that can be used, for example as a service. Instead of a client specifying which service it will use, something tells the client what service to use. The "injection" refers to the passing of a dependency (a service) into the object (a client) that would use it. The service is made part of the client's state.[1] Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.
What does that mean though. Should we never create a StringBuilder object when we use DI? The answer is no (or better yet not always). Can I create a new float without DI? Would it make sense to create a builder service and create the StreamReader from there?
You will see that StreamReader is a very basic implementation public class StreamReader : System.IO.TextReader and the classes do not even implement any other interface other than IDisposable. You can't seriously consider injecting StreamReader for IDisposable in any class.
If you want to decouple from StreamReader then that means that you might want to use something else in the future. You could create a StreamService and create your stream however you like, but at the end of the day the StreamService would have the Coupling as StreamReader can't be injected.
That's why wikipedia infers that Services are injected. Objects might be decoupled but you might want to use other patterns like Factory.
By the way use StreamReader always with the Using keyword so that the object can be properly disposed of.
Dependency Injection is powerful in some points
Testing : Decoupling is essential for unit testing and DI is the good way to achieve that so you can have one interface and Multiple implementations and based on what you want you can write unit test for your code and inject specific concrete class.
Control objects creation : It give you control on how (specific) objects get created and what is the life time of your objects.
So you have to know at the beginning
What type of classes and interfaces you want to centralize/control their objects creation ?
What is the functionality that if any changes happens to it in the future you want your code to keep working without big changes ?
In your case you are using StreamReader, it's a built-in class in C# so you have to think about How many times I'm going to use that class in my code? Do I need to change it in the future?
If I were you I'll think about two options
I don't care about the StreamReader it's a built-in class in C# ,it works well and I'm not going to write unit test to test the StreamReader functionality so I'll use it like what you did in your code sample.
I'm using StreamReader in many places in the code and I've some repeated logic I used to do every time after reading stream so I'll create IStreamReader interface with the main methods I want to use then use the DI to inject the concrete implementation.
Note: while using DI you are not going to Inject all the Objects in your system.
The idea behind Dependency Injection is to avoid creating instances inside a class, but how to deal with this scenario?
That's not at all the point. One of the central points of DI is to enable loose coupling to Volatile Dependencies. Not all types a class depends on are volatile. Some are stable and there is no need to prevent creating stable dependencies from within a class. Chapter one of both Dependency Injection in .NET (by Mark Seemann) and its successor Dependency Injection Principles, Practices, and Patterns (by Mark and I) have a detailed description of what Volatile Dependencies and Stable Dependencies are and how they differ.
The main question you should ask is whether any of the types that WebClientService depend on are Volatile Dependencies or not. The answer depends on your particular context, and you should be able to figure this out after (re)reading chapter 1. This chapter can be read online freely.

What are IDisposable alternative uses?

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.

How best to share an IDisposable object like SqlConnection with several methods in a class?

Sometimes I have several methods all of which connect to SQL Server. This means that all methods contain local variables of IDisposable types like SqlConnection.
What is the best way to reuse one sqlconnection object? Would it be to pass it in as a reference and have it as a class-level variable? Also, if I use it throughout methods, does it need to be passed in by ref and should the class implement idisposable to dispose of the variable?
Thanks
When it comes to SqlConnection, connection pooling will come into play, so in this case the answer is - don't share.
In general, unless a disposable object is designed for sharing, I wouldn't try to share it. There might be some cleanup required before it can be reused without consequence.
I agree with Oded - best practice for using SqlConnection is not sharing it.
If you need to share other IDisposable object between several methods than I would suggest you to implement IDisposable in your class.
Oded's answer is concise and correct; you shouldn't share SqlConnections between using objects.
A more complete answer is that if you want to centralize control of SqlConnections, you should encapsulate them in a Repository object; a centralized database-access object. It has the dual advantage of putting the code that deals with SqlConnections in one place, and hiding that implementation detail from the rest of your code, so if you change to Oracle or MySql or SqLite, you don't have to refactor everything in your system. Do some research on Repository patterns; there should be an example of one or two that will "drop in" to a model that used to handle its own DB calls.
Actually, when you segregate stuff into several methods, a 'shared' connection (inside e.g. a class) may occur. For this, a pattern based on a closure works pretty well:
public void Do() {
WithConnection(o => {
o.Foo();
o.Bar();
});
}
private void WithConnection(Action<ThisClass> action) {
try {
con.Open();
action(this);
}
finally {
con.Dispose()
}
}
I agree that in this special case, pooling may be your friend, but if you want to have a resource available throughout several methods (do several things that would usually fire an event, but you only want the event once, etc. etc.), a closure as shown can be your friend.
I wouldn't share an SqlConnection as Oded says, but I think it might be fine to share a DataContext between methods if you have one. The way I would do that is to let my own data access class implement IDisposable, and in the Dispose method for my data access class I would dispose my DataContext.

A question of style/readability regarding the C# "using" statement

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.

Will calling close() on my WCF service release all resources?

Will calling close on my WCF service kill all resources or set them up for GC or should I set it to null also?
Firstly, WCF proxies are IDisposable, so you can kind of use using:
using(var proxy = new MyProxy()) { // see below - not quite enough
// use proxy
}
Unfortunately, WCF also has a buggy Dispose() implementation that regularly throws exceptions. However, here's a really cool trick to get it to work correctly. I also blogged about this myself, but I think the first link is a lot better.
So: use IDisposable and using, but use it with caution (in this case).
Setting a field usually makes no difference. There are a few edge-cases (such as variables captured by multiple delegates, static fields, long-life objects, etc), but in general leave it alone. In particular, do not do this, as this can theoretically extend the life:
if(field != null) field = null; // BAD
This is not so much a WCF question as a .NET question; see also
Setting Objects to Null/Nothing after use in .NET
Is disposing this object, enough? or do i need to do more?
In the Dispose(bool) method implementation, Shouldn't one set members to null?
You only need to set a variable to null if it's going to be reachable for a long time afterwards. Say, a field on a long-lived object, or a static field. This holds in general, not just for WCF.

Categories

Resources