The FxCop warning "Classes with disposable fields should be disposable" sometimes confuses me. See contrived example below
Only one type creates and owns the disposable resource, but any number of types can use (or "borrow") this resource. I have seen developes take the FxCop warning on Util1 and Util2 to indicate that since they have a field of a disposable type, they must implement Dispose and dispose that field. That's clearly not what you want here.
Is the problem that
Making classes that only borrow disposable resources is an antipattern. The disposable resource could be passed as a method argument to Util1 and Util2, and the problem would go away. Only classes that create disposable resource should ever have them as fields, so that the field itself is what indicates ownership.
The warning isn't clever enough. It should be warning when types that own disposable resources aren't themselves disposable, and in this scenario only one class owns it, while the others borrow it. The fact that it is injected only from a constructor parameter could have been used by a more clever rule to detect that the warning should not be raised for the borrowing class.
Something else?
static class Program
{
public static void Main()
{
using(var r = new SomeResource())
{
Console.WriteLine(new Util1(r).Foo());
Console.WriteLine(new Util2(r).Foo());
}
}
}
public sealed class SomeResource : IDisposable
{
private readonly NativeResource native;
public void SomeResource()
{
native = Native.CreateDisposableThing();
}
public void Dispose()
{
native.Dispose();
}
}
public sealed class Util1 {
private readonly SomeResource res;
public Util1(SomeResource res) { this.res = res; }
public string Foo() { /* uses res */ }
}
public sealed class Util2 {
private readonly SomeResource res;
public Util2(SomeResource res) { this.res = res; }
public string Foo() { /* uses res */ }
}
In most of case if you have a disposable field, it means you want to use it later and wrap it. If you return this field to external code, it can be disposed and break your own class unless you are able to check if resource was disposed before each usage.
If you just want to make a fabric, you don't need to keep the disposble resource as field.
That's why this rules is often true but in some special rare case you are able to make a "won't fix".
Other patterns are pretty rare because it is hard to maintain without introducing bug.
Related
My application creates IDisposable objects that should be reused, so I create a factory that encapsulates the creation and reuse of those objects, code like this:
public class ServiceClientFactory
{
private static readonly object SyncRoot = new object();
private static readonly Dictionary<string, ServiceClient> Clients = new Dictionary<string, ServiceClient>(StringComparer.OrdinalIgnoreCase);
public static ServiceClient CreateServiceClient(string host)
{
lock(SyncRoot)
{
if (Clients.ContainsKey(host) == false)
{
Clients[host] = new ServiceClient(host);
}
return Clients[host];
}
}
}
public class QueryExecutor
{
private readonly ServiceClient serviceClient;
public QueryExecutor(string host)
{
this.serviceClient = ServiceClientFactory.CreateServiceClient(host);
}
public IDataReader ExecuteQuery(string query)
{
this.serviceClient.Query(query, ...);
}
}
What makes me scratch my head is, ServiceClient is IDisposable, I should dispose them explicitly sometime.
One way is implementing IDisposable in QueryExecutor and dispose ServiceClient when QueryExecutor is disposed, but in this way, (1) when disposing ServiceClient, also needs to notify ServiceClientFactory, (2) cannot reuse ServiceClient instance.
So I think it would be much easier to let ServiceClientFactory manage lifetime of all ServiceClient instances, if I go this way, what is the best practice here to dispose all IDisposable objects created by factory? Hook the AppDomain exit event and manually call Dispose() on every ServiceClient instance?
A couple of things to think about here...
Firstly, what you appear to be describing is some variation of the Flyweight pattern. You have an expensive object, ServiceClient, which you want to reuse, but you want to allow consumer objects to create and destroy at will without breaking the expensive object. Flyweight traditionally does this with reference-counting, which might be a bit old hat.
You'll need to make sure that consumers cannot dispose the ServiceClient directly, so you'll also need a lightweight Facade which intercepts the calls to ServiceClient.Dispose and chooses whether to dispose the real object or not. You should hide the real ServiceClient from consumers.
If all that is feasible, you could rewrite your approach as something like:
// this is the facade that you will work from, instead of ServiceClient
public interface IMyServiceClient : IDisposable
{
void Query(string query);
}
// This is your factory, reworked to provide flyweight instances
// of IMyServiceClient, instead of the real ServiceClient
public class ServiceClientFactory : IDisposable
{
// This is the concrete implementation of IMyServiceClient
// that the factory will create and you can pass around; it
// provides both the reference count and facade implementation
// and is nested inside the factory to indicate that consumers
// should not alter these (and cannot without reflecting on
// non-publics)
private class CachedServiceClient : IMyServiceClient
{
internal ServiceClient _realServiceClient;
internal int _referenceCount;
#region Facade wrapper methods around real ServiceClient ones
void IMyServiceClient.Query(string query)
{
_realServiceClient.Query(query);
}
#endregion
#region IDisposable for the client facade
private bool _isClientDisposed = false;
protected virtual void Dispose(bool disposing)
{
if (!_isClientDisposed)
{
if (Interlocked.Decrement(ref _referenceCount) == 0)
{
// if there are no more references, we really
// dispose the real object
using (_realServiceClient) { /*NOOP*/ }
}
_isClientDisposed = true;
}
}
~CachedServiceClient() { Dispose(false); }
void IDisposable.Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
// The object cache; note that it is not static
private readonly ConcurrentDictionary<string, CachedServiceClient> _cache
= new ConcurrentDictionary<string, CachedServiceClient>();
// The method which allows consumers to create the client; note
// that it returns the facade interface, rather than the concrete
// class, so as to hide the implementation details
public IMyServiceClient CreateServiceClient(string host)
{
var cached = _cache.GetOrAdd(
host,
k => new CachedServiceClient()
);
if (Interlocked.Increment(ref cached._referenceCount) == 1)
{
cached._realServiceClient = new ServiceClient(host);
}
return cached;
}
#region IDisposable for the factory (will forcibly clean up all cached items)
private bool _isFactoryDisposed = false;
protected virtual void Dispose(bool disposing)
{
if (!_isFactoryDisposed)
{
Debug.WriteLine($"ServiceClientFactory #{GetHashCode()} disposing cache");
if (disposing)
{
foreach (var element in _cache)
{
element.Value._referenceCount = 0;
using (element.Value._realServiceClient) { }
}
}
_cache.Clear();
_isFactoryDisposed = true;
}
}
~ServiceClientFactory() { Dispose(false); }
void IDisposable.Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
// This is just an example `ServiceClient` which uses the default
// implementation of GetHashCode to "prove" that new objects aren't
// created unnecessarily; note it does not implement `IMyServiceClient`
public class ServiceClient : IDisposable
{
private readonly string _host;
public ServiceClient(string host)
{
_host = host;
Debug.WriteLine($"ServiceClient #{GetHashCode()} was created for {_host}");
}
public void Query(string query)
{
Debug.WriteLine($"ServiceClient #{GetHashCode()} asked '{query}' to {_host}");
}
public void Dispose()
{
Debug.WriteLine($"ServiceClient #{GetHashCode()} for {_host} was disposed");
GC.SuppressFinalize(this);
}
}
Secondly, in general, I'd remove the static clauses from the factory and make ServiceClientFactory : IDisposable. You'll see I've done that in my example above.
It may seem like you're just pushing the problem up the chain, but doing so allows you to make this decision on a case-by-case basis, per-something (application, session, request, unit test run -- whatever makes sense) and have the object that represents your something be responsible for the disposal.
If your application would benefit from a single-instance cache then expose a singleton instance as part of an AppContext class (for example) and call AppContext.DefaultServiceClientFactory.Dispose() in your clean-shutdown routine.
The emphasis here is on a clean shutdown. As others have stated, there is no guarantee that your Dispose method will ever actually be called (think power-cycling the machine, mid-run). As such, ideally, ServiceClient.Dispose would not have any tangible side-effects (i.e. beyond freeing resources that would be freed naturally if the process terminates or the machine power-cycles).
If ServiceClient.Dispose does have tangible side-effects, then you have identified a risk here, and you should clearly document how to recover your system from an "unclean" shutdown, in an accompanying user manual.
Thirdly, if both ServiceClient and QueryExecutor objects are intended to be reusable, then let the consumer be responsible for both the creation and disposal.
QueryExecutor only really has to be IDisposable in your sample because it can own a ServiceClient (which is also IDisposable). If QueryExecutor didn't actually create the ServiceClient, it wouldn't be responsible for destroying it.
Instead, have the constructor take a ServiceClient parameter (or, using my rewrite, an IMyServiceClient parameter) instead of a string, so the immediate consumer can be responsible for the lifetime of all objects:
using (var client = AppContext.DefaultServiceClientFactory.CreateServiceClient("localhost"))
{
var query = new QueryExecutor(client);
using (var reader = query.ExecuteReader("SELECT * FROM foo"))
{
//...
}
}
PS: Is there any need for consumers to actually directly access ServiceClient or are there any other objects which need a reference to it? If not, perhaps reduce the chain a little and move this stuff directly to QueryExecutor, i.e. using a QueryExecutorFactory to create flyweight QueryExector objects around cached ServiceClient instances, instead.
Static classes are tricky that way. The constructor for a static class is invoked when an instance member is first invoked. The class is destroyed if and when the application domain is destroyed. If the application terminates abruptly (aborts), there's no guarantee a constructor/finalizer would be called.
Your best bet here is to redesign the class to use a singleton pattern. There are ways to work around this issue, but they require strange, dark magic forces that may cost you your soul.
EDIT: As servy points out, a Singleton won't help here. A destructor is a finalizer, and you won't have any guarantee that it will be called (for a wide variety of reasons). If it were me, I'd simply refactor it to an instantiable class that implements IDisposable, and let the caller deal with calling Dispose. Not ideal, I know, but it's the only way to be sure.
I'm trying to use the AutoMapper for model-viewmodel mapping and wanted to have the mapping configuration executed once in the static constructor of the type. The static constructor of a type is not invoked when Mapper.Map (AutoMapper) is invoked with that type.
My understanding is that the Mapper.Map would try to access the type, its members through reflection and on the first attempt of the usage the static constructor would be called. This is something basic but challenges my understanding. The code snippet is provided.
class SampleViewModel
{
static SampleViewModel()
{
Mapper.Initialize(cfg => cfg.CreateMap<Sample, SampleViewModel>().ReverseMap());
}
public SampleViewModel()
{
}
public int PropertyA { get; set; }
public int PropertyB { get; set; }
}
Sample s = new Sample { PropertyA = 10, PropertyB = 20 };
var obj = Mapper.Map<SampleViewModel>(s); // fails
Isn't the static constructor called (if provided) when the type and members are accessed through reflection for the first time?
You're not accessing any members of SampleViewModel - it's not enough to just reference the type itself.
Mapper.Map only accesses its own internal "dictionary" of mappings - before it could ever get to a point where it deals with a SampleViewModel, it fails. The static constructor never runs, so it cannot add "itself" into the Mapper.
Now, if this didn't involve reflection, you would be right that the static constructor would be called - simply because it would happen during the compilation of the method containing the access, e.g.:
var obj = Mapper.Map<SampleViewModel>(s);
Console.WriteLine(obj.SomeField);
In this case, since the method is referencing a field on SampleViewModel, the static constructor for SampleViewModel will be invoked during JIT compilation of the containing method, and as such, the Mapper.Map<SampleViewModel>(s) line will execute correctly, since the mapping is now present. Needless to say this is not the proper solution to your problem. It would just make the code absolutely horrible to maintain :)
DISCLAIMER: Even though this might fix the problem right now, it depends on a non-contractual behaviour in the current implementation of MS.NET on Windows. The contract specifies that the type initializer is invoked before any access to a member of the type, but that still means that a valid implementation of CIL might only call the type initializer after Mapper.Map, as long as it happens before obj.SomeField - and even then, it might be that obj.SomeField gets optimized away if the compiler can ensure it is safe to do so. The only real way to enforce the call of the type initializer is to call RuntimeHelpers.RunClassConstructor, but by that point, you could just as well add a static Init method or something.
The real problem is that you shouldn't really initialize stuff like this in a static constructor in the first place. Mappings should be set in some kind of deterministic initialization process, say, an explicitly invoked InitMappings method. Otherwise you're opening yourself to a huge can of Heisenbugs, not to mention subtle changes in the CLR breaking your whole application for no apparent reason.
Static constructors just aren't meant for "registration", just the initialization of the type itself - anything else is an abuse, and will cause you (or the .NET compatibility team) trouble.
Static constructors run at an implementation-defined time just before the first instance of that class is created, or before any static member of that type is accessed. See When is a static constructor called in C#?.
The mapper tries to find a mapping before doing its work of instantiating the class to map into, and thus can't find a mapping, because the class was never instantiated before that moment.
Just move your mapping initialization code into a AutoMapperBootstrap.cs file or something, and call that in your application initialization.
".. The static constructor of a type is not invoked when Mapper.Map (AutoMapper) is invoked with that type..."
I tested your scenario and observed that the static constructor is indeed being called before the first instance of the object is created.
C# Programming Guide: Static Constructors
I also went ahead and modified the sample code by adding a GetMapper function which returns an IMapper. This might seem like an overkill for day-to-day simple mapping, but if we need an object to give us its mapper, perhaps we can get it from a static method.
One can easily move the responsibility of creating the Mapper object to a factory or a DI container which, for the sake of simplicity, I did not include here.
Worth noting that in this example, the static fields are initialized before the static constructor which is called right after the static read-only fields are initialized.
Uses AutoMapper v12.0 and .Net Core 3.1.
public class SimpleObjectToMap
{
private static readonly MapperConfiguration _simpleObjMapperConfig = new MapperConfiguration(
config => config.CreateMap<SimpleObjectToMap, ObjectToBeMappedTo>());
private static readonly IMapper _mapper = new Mapper(_simpleObjMapperConfig);
private int _propertyA;
public int PropertyA
{
get
{
Console.WriteLine("ObjectToMap.PropertyA.Get");
return _propertyA;
}
set { _propertyA = value; }
}
static SimpleObjectToMap()
{
Console.WriteLine("*** ObjectToMap static ctor called ***");
}
public static IMapper GetMapper()
{
return _mapper;
}
}
public class ObjectToBeMappedTo
{
static ObjectToBeMappedTo()
{
Console.WriteLine("*** ObjectToBeMappedTo static ctor called ***");
}
private int _propertyA;
public int PropertyA
{
get { return _propertyA; }
set
{
Console.WriteLine("ObjectToBeMappedTo.PropertyA.Set");
_propertyA = value;
}
}
}
public class TestObjectMappingWithStaticCtor
{
public void TestWithStaticCtor()
{
SimpleObjectToMap objToMap = new SimpleObjectToMap { PropertyA = 27 };
var mappedObject = SimpleObjectToMap.GetMapper().Map<ObjectToBeMappedTo>(objToMap);
}
}
Basically I have a few functions that look like this:
class MyClass
{
void foo()
{
using (SomeHelper helper = CreateHelper())
{
// Do some stuff with the helper
}
}
void bar()
{
using (SomeHelper helper = CreateHelper())
{
// Do some stuff with the helper
}
}
}
Under the assumption I can use the same resource instead of a different one [instance] in every function is it ok practice in regard to cleanup and such to do this?:
class MyClass
{
SomeHelper helper = CreateHelper();
// ...foo and bar that now just use the class helper....
~MyClass()
{
helper.Dispose();
}
}
No, do not add a destructor (Finalizer).
You can reuse the resource but then your class has to implement IDisposable.
sealed class MyClass : IDisposable
{
SomeHelper helper = CreateHelper();
// ...foo and bar that now just use the class helper....
//~MyClass()
public void Dispose()
{
helper.Dispose();
}
}
And now you have to use MyClass instances in a using block. It self has become a managed resource .
A destructor is of no use, whenever a MyClass instance is being collected the associated helper object will also be in the same collection. But having a destructor still incurs considerable overhead.
The standard pattern for IDisposable uses a virtual void Dispose(bool disposing) method but when making the class sealed you can use the minimalistic implementation above.
In .NET you don't know when (or whether) finalizer is called at all.
Instead, explicitly indicate that your class is to be disposed of by implementing IDisposable:
(This is exactly what SomeHelper does)
class MyClass : IDisposable
{
readonly SomeHelper helper = CreateHelper();
// any method can use helper
public void Dispose()
{
helper.Dispose();
}
}
using(var myObj = new MyClass()) {
// at the end, myObj.Dispose() will trigger helper.Dispose()
}
I used readonly to ensure helper doesn't get re-assigned somewhere else in the class, but this really doesn't matter if you're careful.
You must be extra careful to never set it to null, or your Dispose will throw an exception. If the field is protected, you can check for nullity before calling Dispose on it so you know you're playing safe.
You can share such a resource during the lifetime of your object, in which case it is recommended that you implement IDisposable.
No, it is not. You don't know when the finalized will un. Also, if your resource is managed, it will be disposed of at some point without the finalized.
If you don't want to use using all the time, perhaps ou can use it once around many functions.
You don't need to override the finalizer in your object, which you have shown in your second code sample by ~MyClass().
You will need to implement the IDisposable pattern. You haven't been explicit in your question if you are using managed and unmanaged resources, but here's a quick sample for a managed resource. Stackoverflow has a myriad of examples on this. Reed Copsey also has a good series on it, and you can start here.
class MyClass : IDisposable
{
private bool _Disposed;
private SomeHelper _Helper;
protected virtual void Dispose()
{
this.Dispose(true);
}
public void Dispose(bool disposing)
{
if (_!Disposed && disposing)
{
if (_Helper != null)
_Helper.Dispose();
_Disposed = true;
}
}
}
The convention is that if your class owns an IDisposable object it should also implement IDisposable. So rather than implementing a finalizer your class should implement IDisposable and dipose of the helper there.
One problem with implementing the finalizer is that you have no control over when it's being called. The disposable pattern gives you a more deterministic way of cleaning up resources.
Basically, is there an easy way to dispose of the imports that are created by an ExportFactory<T>? The reason I ask is because the exports usually contain a reference to something that is still around, such as the EventAggregator. I don't want to run into the issue where I'm creating hundreds of these and leaving them laying around when they are not necessary.
I noticed that when I create the objects I get back a ExportLifetimeContext<T> which carries a Dispose with it. But, I don't want to pass back an ExportLifetimeContext to my ViewModels requesting copies of the ViewModel, hence I pass back the Value. (return Factory.Single(v => v.Metadata.Name.Equals(name)).CreateExport().Value;)
When you call Dispose on an ExportLifetimeContext<T> it will call dispose on any NonShared part involved in the creation of T. It won't dispose of any Shared components. This is a safe behaviour, because if the NonShared parts were instantiated purely to satisfy the imports for T, then they can safely be disposed as they won't be used by any other imports.
The only other way I think you could achieve it, would be to customise the Dispose method to chain the dispose call to any other member properties you import with, e.g.:
[Export(typeof(IFoo))]
public class Foo : IFoo, IDisposable
{
[Import]
public IBar Bar { get; set; }
public void Dispose()
{
var barDisposable = Bar as IDisposable;
if (barDisposable != null)
barDisposable.Dispose();
}
}
But as your type has no visibility of whether the imported instance of IBar is Shared or NonShared you run the risk of disposing of shared components.
I think hanging onto the instance of ExportedLifetimeContext<T> is the only safe way of achieving what you want.
Not sure if this helps, feels like unnecessary wrapping, but could you possibly:
public class ExportWrapper<T> : IDisposable
{
private readonly ExportLifetimeContext<T> context;
public ExportWrapper<T>(ExportLifetimeContext<T> context)
{
this.context = context;
}
public T Value
{
get { return context.Value; }
}
public void Dispose()
{
context.Dispose();
}
public static implicit operator T(ExportWrapper<T> wrapper)
{
return wrapper.Value;
}
public static implicit operator ExportWrapper<T>(ExportLifetimeContext<T> context)
{
return new ExportWrapper<T>(context);
}
}
Which you could possibly:
[Import(typeof(IBar))]
public ExportFactory<IBar> BarFactory { get; set; }
public void DoSomethingWithBar()
{
using (ExportWrapper<IBar> wrapper = BarFactory.CreateExport())
{
IBar value = wrapper;
// Do something with IBar;
// IBar and NonShared imports will be disposed of after this call finishes.
}
}
Feels a bit dirty...
Suppose that your code is properly designed for DI and IOC through constructor injection of any dependencies. Then whether an IOC container or DI-by-hand is used or not at the composition root doesn't matter much for this problem. I think.
Anyway, I find myself over and over again in a mental struggle with how I should best deal with scope-based services, like transactions or other obviously transient operations. There are constraints that I want to abide to:
Don't let dependency interfaces be IDisposable - it's a leaky abstraction that only the actual implementing type (and the fiddler sitting at the composition root) should care about.
Don't use static service locator types deep down the graph to resolve a dependency - only inject and resolve through the constructor.
Don't pass the IOC container, if any, as a dependency down the graph.
To be able to use using, we need IDisposable, but since a dependency interface shouldn't be IDisposable, how do you get around it to get scoped behavior?
In cases like this I would inject a service factory that creates those scoped services and let the service interface derive from IDisposable. This way the factory would be responsible to create the appropriate service instances and the only point that decides which service implementation to return. You would not need to inject the scoped service anywhere.
public interface ITransaction : IDisposable
{
}
public interface ITransactionFactory
{
ITransaction CreateTransaction();
}
public class Foo
{
private readonly ITransactionFactory transactionFactory;
public Foo(ITransactionFactory transactionFactory)
{
this.transactionFactory = transactionFactory;
}
public void DoSomethingWithinTransaction()
{
using(ITransaction transaction = this.transactionFactory.CreateTransaction())
{
DoSomething();
}
}
}
Most IoC containers today have substantial built-in support for units of work of this nature.
In Autofac, the mechanism that best fits your requirements is the Owned<T> relationship type. You can see it in action (and get some more material) via this article.
Hope this helps,
Nick
Roll your own "garbage collector" maybe? Something that periodically checks IsComplete and/or an LastAccessed attribute of a Dictionary<Transaction> and wastes the "old" ones. It's "a walking memory leak" but either you clean-up explicitly (like through IDisposable) or you workout how to clean-up automatically.
There may be an AOP solution to kicking-off the "gc"... a commit/rollback sounds like a good place to cut... and maybe you won't even need a GC at all... just cleanup the transaction on the way back-up the callstack from commit or rollback.
Good luck with it. I'll be interested to see what solutions (and ideas) other people come-up with.
Cheers. Keith.
I guess another alternative you could use is to wrap your instances with a disposable type, that way it could automatically handle the disposal of the type regardless of whether the type is actually disposable. E.g, I could define something like:
public class DisposableWrapper<T> : IDisposable
{
private readonly T _instance;
private readonly IDisposable _disposable;
public DisposableWrapper(T instance)
{
_instance = instance;
_disposable = instance as IDisposable;
}
public void Dispose()
{
if (_disposable != null)
_disposable.Dispose();
}
public static implicit operator T(DisposableWrapper<T> disposableWrapper)
{
return disposableWrapper._instance;
}
}
(Hopefully with a bit more error handling!)
Given that I know at the point of disposal whether the type is disposable, I can call it accordingly. I can also provide an implicit operator to cast back to the inner type from it. With the above, and a nifty extension method:
public static class DisposableExtensions
{
public static DisposableWrapper<T> Wrap<T>(this T instance)
{
return new DisposableWrapper<T>(instance);
}
}
Let's imagine that I have a service I am injecting into a type, it could be:
public interface IUserService
{
IUser GetUser();
}
I could potentially do something like:
public HomeController(IUserService service)
{
using (var disposable = service.Wrap())
{
var user = service.GetUser();
// I can even grab it again, implicitly.
IUserService service2 = disposable;
}
}
Now regardless of whether that concrete implementation of IUserService is disposable or not, I can still safely work on the assumption that it doesn't matter.
Another quick console example:
class Program
{
static void Main(string[] args)
{
using (var instance = new ClassA().Wrap())
{
ClassA instanceA = instance;
}
using (var instance = new ClassB().Wrap())
{
ClassB instanceB = instance;
}
Console.ReadKey();
}
}
public class ClassA
{
}
public class ClassB : IDisposable
{
public void Dispose()
{
Console.Write("Disposed");
}
}