using statement; why is my field not set to null? - c#

I am trying to minimize entity framework connection context scope using "using" while at the mean time I want to be able to inject a context into my class.
I searched on internet but did not find a case like mine, or I am just doing something wrong, anyway, here is code:
[TestFixture]
public class Dummy
{
private IFoo ifoo;
[Test]
public void CreateIfNotExist()
{
using (var foo = GetNewIFoo())
{
foo.Dosomething();
}
Assert.IsNull(ifoo);//test fail here
}
[Test]
public void NotCreateIfExist()
{
ifoo = new Bar();
using (var foo = GetNewIFoo())
{
foo.Dosomething();
}
Assert.IsNull(ifoo);//test fail here
}
private IFoo GetNewIFoo()
{
if (ifoo == null)
{
ifoo = new Foo();//return new Foo();
}
return ifoo;
}
}
the first test failed, with a object sequence of foo created->foo do something->foo disposed(called by using on foo) while the state variable ifoo is still type of Foo().
Second test failed, with object life sequence as same as before.
I am confused as I thought GetNewIFoo() would return a reference of ifoo and using keyword would just call dispose on ifoo?
Also, is there any good way to control context scope while maintaining ability to inject IContext ?

Calling Dispose() does not clear the references (nor does it perform garbage collection). It simply calls the Dispose() method, which can (for example) close connections, files, etc - depending on the implementation. An object can be non-null and still disposed. Some objects allow you to see if an object is disposed; most don't.
Generally, if you are using something, you wouldn't write that variable somewhere else (i.e. you wouldn't write it as a field somewhere).

Meaning if using block is in next:
using (var foo = GetNewIFoo())
{
foo.Dosomething();
} // foo.Dipose() will be called automatically
which is the same as:
var foo = GetNewIFoo())
try
{
foo.Dosomething();
}
finally
{
foo.Dipose();
}
so foo is not null after using, but it's disposed.
Also:
using (var foo = GetNewIFoo())
{
foo.Dosomething();
}
//^ nothing below affects ifoo!!
Assert.IsNull(ifoo); // so why reference should be null??

Related

What is the lifetime of a property with only a getter

Lets assume I instantiated MyClass. Does my Foo property have a reference at this point or is it null? Also what happens after I call UseFoo() and exit the scope? Did I dispose Foo or just foo?
public class MyClass
{
private readonly string param;
private IDisposable Foo => new Foo(param);
public MyClass(string param)
{
this.param = param;
}
public void UseFoo()
{
using var foo = Foo;
// use foo
}
}
Q: Does my Foo property have a reference at this point or is it null?
A: No, because the property does not have a backing field, aka state.
Instead, every time you read the value of Foo, you will construct a new instance of the Foo type and return that.
As #juharr so nicely put it in their comment, it is a property but behaves like a method.
Q: Also what happens after I call UseFoo() and exit the scope? Did I dispose Foo or just foo?
A: You disposed the single object that you got from reading the Foo property and stored in the foo local variable.
Since the Foo property does not actually have state, you only disposed the object that was constructed for you when you read the Foo property.
The next time you read the Foo property you will get a new instance.
I find it helpful to mentally translate => to "returns". It is an active operation, not a passive assignment. So in your case, I would read it as "Foo returns a new foo of param".
When it comes to properties,
private IDisposable Foo => new foo(param);
is equivalent to
private IDisposable Foo
{
get { return new foo(param); }
}

Should I Dispose Object Passed Through Constructor If Other Constructors Create It?

Given the following code, should I only dispose foo when it was created by within the Bar class? Or should I always dispose foo even when it was passed to a constructor? I'm thinking I should probably add another private variable to keep track of whether Bar created foo or whether it was passed to the Bar( Foo foo ) constructor, and only dispose of foo when it was created by the public Bar( string name ) constructor.
public class Bar: IDisposable
{
private Foo foo = null;
public Bar( string name )
{
this.foo = new Foo(name);
}
public Bar( Foo foo )
{
this.foo = foo;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose( bool disposing )
{
if( disposed )
return;
if( disposing )
foo.Dispose();
this.disposed = true;
}
}
You're correct in your thinking.
If you're passed an instance of Foo from elsewhere, and dispose of it yourself, you might break code still consuming the Foo. If you create an instance of Foo but don't dispose of it, you'll hang on to the memory it consumes unnecessarily long.
So, your best option is to track whether you created the instance yourself and dispose of it if so. (You could also allow the caller to specify the behaviour, as has been mentioned in the comments.)
(Alternatively, you could not do anything, which will be more inefficient but will at least not break anything. The only solution that is likely to actively break something is if you dispose of the instance that's been passed in from elsewhere.)

Transferring ownership of an IDisposable object and the builder design pattern

I'm used to the approach when it is the object that creates another object (either directly or through factories, builders, etc) - is the one that "owns" it, thus manages its lifetime.
This idea works fine in almost every case.
But sometimes the one that creates an object simply cannot manage it, for instance in the builder design pattern implementation:
IFoo BuildFoo()
{
var dep = new Dep();
return new Foo(dep);
}
So, here the builder cannot manage the lifetime of the dep object since:
it does not have a reference to it;
it does not know when it is safe to Dispose it.
The naive solution would be to make Foo : IDisposable and let it manage the Dep passed to its constructor.
But then another dilemma arises:
using (var dep = new Dep())
{
using (var foo = new Foo(dep))
{
// (1) do something with foo
}
// (2) !!! do something with dep !!!
}
The code above becomes unsafe: at the point (2) it's not safe to use dep since it is already Disposed by foo.
And there is nothing syntactically that can denote, whose responsibility it is to manage the lifetime of an object.
So the question: what would be a general solution for that?
In this case, I wouldn't worry about it. I'm going to get shot to pieces here, I imagine, but "builders", "factories" etc are all places where I think it's okay to create an object and hand off it's disposal to the thing that asked for it.
There is a rule though that the builder/factory must only be creating the object, and not doing anything with it.
Of course, if you're newing-up objects using the new keyword, then you're coupling yourself to that implementation (even if it's indirectly via a factory class). You might want instead to consider dependency injection, depending on what the created objects are for, in which case a DI container would create the objects and dispose them for you at the correct time, based on their configured lifestyle.
very naive implementation
void Main()
{
using (var builder = new Builder())
{
var foo = builder.Create();
// do smtg
}
}
public class Foo
{
public Foo(Dep instance)
{
}
}
public class Dep : IDisposable
{
public void Dispose()
{
Console.WriteLine($"{this.GetType().Name} disposed!");
}
}
public class Builder : IDisposable
{
private List<IDisposable> _disposables = new List<System.IDisposable>();
public Foo Create()
{
var dep = new Dep();
_disposables.Add(dep);
var foo = new Foo(dep);
return foo;
}
public void Dispose()
{
foreach(var d in _disposables)
d.Dispose();
Console.WriteLine($"{this.GetType().Name} disposed!");
}
}
If something owns IDisposable, then it should implement IDisposable.
And, ofcourse, this is very naive impl, just as sample.
What about you let Foo call the builder to instantiate Dep and use it whenever it needs to. This way Foo manages the lifetime of Dep without the client of Foo having to worry about it.

Will Dispose() be called if a .ctor() throws?

I've got a class with one IDisposable member variable initialized in-line, and another IDisposable in the constructor.
Will Dispose() be called if the constructor throws? If so, then I presume the null check is necessary...? If not, then how does the in-line member get disposed?
sealed class SomeDisposable : IDisposable { ... }
sealed class Foo : IDisposable
{
readonly SomeDisposable sd1= new SomeDisposable(); // this doesn't throw
readonly SomeDisposable sd2;
public Foo()
{
sd2 = new SomeDisposable(); // assume this throws
// how does sd1 get Dispose()d?
}
public void Dispose()
{
sd1.Dispose();
if (sd2!= null) // is this null check necessary?
sd2.Dispose();
}
}
There is at present no way in C# to safely initialize an IDisposable with an in-line initializer except through a nasty hack involving ThreadStatic variables. The constructor must be called via factory method that creates a disposal-manager object and stores a reference in a thread-static field. Field initializers can then wrap their value in a call to a static method which will add them to the disposal-manager object.
The actual field-initializer syntax ends up being pretty reasonable:
DisposalManager Cleaner = DisposalManager.CurrentManager;
DType1 DField1 = DisposalManager.Guard(new DType1);
DType2 DField2 = DisposalManager.Guard(new DType2);
so does the Dispose cleanup:
void Dispose(bool disposing)
{
Cleaner.Cleanup(disposing);
}
Unfortunately, the needs to have every single call to Guard do its own access to the thread-static field, and to have all constructor calls wrapped in factory methods, makes the construct rather ugly. Too bad, since being able to use a single line to declare, create, and clean up a field is much nicer than having to do those things at three separate places in the code.
Lets assume you're using the following code in the form:
var foo = new Foo(someByteArray);
And your constructor throws an exception, then foo will be null, because the class constructor didn't complete. Any attempt to call it's Dispose will cause a NRE to occur.
Interesting question.
Tried this:
try
{
//caller
using (var x = new Disposable1()) { }
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
public class Disposable1 : IDisposable
{
private Disposable2 first = new Disposable2();
private Disposable2 second;
public Disposable1()
{
second = new Disposable2("Goodbye!");
}
public void Dispose()
{
Debug.WriteLine("Disposable1.Dispose()");
first.Dispose();
if (second != null)
second.Dispose();
}
}
public class Disposable2 : IDisposable
{
public string Whatever { get; set; }
public Disposable2() { Whatever = "Hello!"; }
public Disposable2(string whatever)
{
Whatever = whatever;
throw new Exception("Doh!");
}
public void Dispose()
{
Debug.WriteLine("Disposable2.Dispose()" + Whatever);
}
}
...and the output was...
Doh!
So it does appear that neither member is initialized or disposed.

Blocking getters while async task completes

I constantly load objects from the database. Usually I would load the object when I need it, and in the constructor I call the database and populate all the methods I need to.
What I had done to speed up this process was create a task in the constructor and use wait before I returned the value in a getter. For example
Before:
class Foo{
public string Bar {get;set;}
public Foo(int id){
DataRow res;
//Do database operations
Bar = res["Bar"].ToString()
}
}
Now:
class Foo{
private Task LoadTask;
private string _Bar;
public string Bar {
get {
LoadTask.Wait();
return _Bar;
}
set {
_Bar = value;
}
}
public Foo(int id){
LoadTask = Task.Factory.StartNew(() => {
DataRow res;
//Do database operations
Bar = res["Bar"].ToString();
});
}
}
What I am wanting to do is extend a class, where in the constructor it fires off this task, calls an overridden method in the sub class and then block any getting of any property until the task completes.
The most I found was this, but not to sure if its what I want at all
http://www.gutgames.com/post/Overridding-a-Property-With-ReflectionEmit.aspx
As I said earlier, I think this design can be improved, but I appreciated the technical challenge so I gave it a shot.
What you talked about sounded not too dissimilar to Entity Framework's dynamically created change tracking proxies, so I had a quick look around for frameworks which work with dynamic proxies and quickly settled on Castle Project (http://www.nuget.org/packages/Castle.Core) as my weapon of choice.
Naive implementation
This is what we're going for at this stage:
Foo foo = Foo.Factory.Create<Foo>();
foo.Bar = "Zzz"; // Runs immediately.
string bar = foo.Bar; // Blocks until initialisation has completed.
Let's leave out inheritance for now (pretend that Foo is sealed).
We want Foo to have no public constructors forcing the consumer to instantiate it via Foo.Factory.Create<Foo>(), which returns a dynamic proxy derived from Foo with an additional bit of functionality injected into every virtual property getter invocation: wait for the initialisation tasks to complete.
using System.Collections.Generic;
using System.Threading.Tasks;
using Castle.DynamicProxy;
public class Foo
{
// Fields.
protected readonly List<Task> InitialisationTasks = new List<Task>();
// Properties.
// These have to be declared virtual
// in order for dynamic proxying to work.
public virtual string Bar { get; set; }
protected Foo()
{
// Initialisation work.
this.InitialisationTasks.Add(Task.Delay(500));
}
// Responsible for instantiating dynamic
// proxies of Foo and its derivatives.
public static class Factory
{
// Static fields.
static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator();
static readonly WaitForInitInterceptor Interceptor = new WaitForInitInterceptor();
// Factory method.
public static T Create<T>() where T : Foo
{
return ProxyGenerator.CreateClassProxy<T>(Interceptor);
}
class WaitForInitInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// Applies to getters only.
if (invocation.Method.Name.StartsWith("get_"))
{
var foo = invocation.InvocationTarget as Foo;
if (foo != null)
{
// Block until initialisation completes.
Task.WhenAll(foo.InitialisationTasks).Wait();
}
// Continue to the target method.
invocation.Proceed();
}
}
}
}
}
So far so good, but by the sound of it we'll also have to deal with inheritance. The existing design will not support that, because:
the derived class can introduce a public constructor thereby bypassing proxy creation via Foo.Factory.Create<Foo>() - we need to disallow that.
any properties in a derived type need to declared virtual so that their getter invocations can be intercepted by the proxy.
Tweaking to support inheritance
Reflection to the rescue:
public class Foo
{
// Fields.
protected readonly List<Task> InitialisationTasks = new List<Task>();
// Properties.
// These have to be declared virtual
// in order for dynamic proxying to work.
public virtual string Bar { get; set; }
protected Foo()
{
// Enforce proxy integrity.
this.Validate();
// Initialisation work.
this.InitialisationTasks.Add(Task.Delay(500));
}
private void Validate()
{
var type = ProxyUtil.GetUnproxiedType(this);
// No public constructors.
if (type.GetConstructors().Length != 0)
{
throw new InvalidOperationException(
"Public constructors not supported in derived types."
);
}
// No non-virtual properties.
foreach (var property in type.GetProperties())
{
// We're only interested in getters.
var method = property.GetGetMethod();
if (method != null && !method.IsVirtual)
{
throw new InvalidOperationException(
"Only virtual properties are supported."
);
}
}
}
// Responsible for instantiating dynamic
// proxies of Foo and its derivatives.
public static class Factory
{
// Static fields.
static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator();
static readonly WaitForInitInterceptor Interceptor = new WaitForInitInterceptor();
// Factory method.
public static T Create<T>() where T : Foo
{
return ProxyGenerator.CreateClassProxy<T>(Interceptor);
}
class WaitForInitInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// Applies to getters only.
if (invocation.Method.Name.StartsWith("get_"))
{
var foo = invocation.InvocationTarget as Foo;
if (foo != null)
{
// Block until initialisation completes.
Task.WhenAll(foo.InitialisationTasks).Wait();
}
// Continue to the target method.
invocation.Proceed();
}
}
}
}
}
Now if we were to create class FooDerived : Foo which has a public constructor or non-virtual properties (properties that don't have a getter are exempt from this rule), the base constructor will throw thereby forcing the consumer to use Foo.Factory.Create<FooDerived>().
If FooDerived needs to perform its own asynchronous initialisation work, it can just add its own tasks to InitialisationTasks - any property getter will block until all of them have completed.
This code is a bit rough due to each 'Foo' proxy initialisation doing a lot of intensive work behind the covers (via Validate). In an ideal world I would have some kind of cache (perhaps a dictionary) of types which have already passed the validation, and skip the slow Reflection-bound validation for those.
Alternative approach
While dynamic proxies are fun, the design is flawed. The concerns are not well-separated. Foo shouldn't really be worrying about pulling out its own data in the first place, and definitely shouldn't be worrying about Tasks, thread pool and the like. This was discussed extensively in the comments, and I think your best bet really is to kick off the data loading tasks at the point where you have enough information to do so, save the Task references (or whatever other async unit of work you're using), and then await them (or block by getting Result or calling Wait) when you need to use the fully-loaded instance. This ensures that your Foo instances are not accessible until the loading is fully finished and gives you reasonable control over how the async object loading is scheduled. You could, for example, roll your own limited concurrency scheduler, or use ConcurrentExclusiveSchedulerPairs ExclusiveScheduler to ensure that you are not flooding the thread pool with work. Batching object loading (using Task<IEnumerable<Foo>> instead of IEnumerable<Task<Foo>>, for example) is another good way of keeping tabs on the number of tasks you create. It's easy to get creative with async loading once you decouple it from your object construction logic, and it's almost certainly the right way to go.

Categories