This will likely be my last post on the subject of the major changes coming in SlimDX 2 for a little while. My last few posts have focused on issues we’re fairly certain will be relevant to the new API (as will this post) — but we don’t have everything planned out yet. We have a few ideas we’d like to experiment with, but we’re going to have to take some time to prototype them and mess around before we can commit to any one solution. Indeed, there are even a few unanswered questions about the topic I’m going to talk about today.
That topic is how we’re not going to use IDisposable any longer.
More specifically, we’re not going to use it as much. Almost every SlimDX 1 object implements IDisposable, because IDisposable is all about cleaning up unmanaged resources and SlimDX objects are, for the most part, exactly that. But the sort of resources IDisposable is geared towards are those with very explicit lifetimes: you create it, do your thing, and then Dispose() of it. C# using-blocks allow you to implement this exact pattern for locally-held objects quite efficiently.
Long-time readers will recall that our IDisposable wrappers around COM objects have caused us a lot of trouble in the past, largely because the interface’s contract does not really jive with COM’s reference counting. To account for this, we implemented an object table based loosely on the same principles that the .NET RCW uses — specifically, we tried to maintain exactly one COM reference to any object known to SlimDX so that we could do the correct thing when Dispose() was called. This eventually led us to an overly-complicated system burdened with multiple creation code paths and inconsistent ownership semantics.
Our solution is to, essentially, side-step the issue entirely and just expose the reference counting directly. All SlimDX 2 objects that are backed by actual COM interfaces implement IComObject, which provides the familiar-looking methods AddReference() and Release(). For the trivial scenarios where you just want quick, scoped access to a COM object, we’ll be providing a simple IDisposable utility wrapper you can use in conjunction with a using-block to automatically drop the reference count when appropriate.
While it first might seem like this change is a step backwards, we think that it’s an improvement in the long run: it obviates the need for the exceedingly complex object ownership rules that existed with SlimDX 1 (which, we suspect, most of our users were getting wrong). Plus, it makes the SlimDX ownership semantics match those of the already-familiar native API.
Tags: com, design, refactoring, slimdx