A place for spare thoughts

28/11/2014

Re: DI vs DIP vs IoC

Filed under: patterns — Ivan Danilov @ 06:59

Have just read blog post about the subject (in Russian).

I’m an absolute “fan” of definitions which “forgot” to define things and just trying to explain them with examples. Such as “it is when you have …”. Fabulous. And useless. I do agree with DIP description, partially agree with DI description and find IoC description plainly wrong.

Yes, sure, difference between a library and a framework is defined by who controls execution environment. IoC is related to that topic, but it is not this difference itself.

Inversion of Control is a principle that allows one part of code (often general and reusable) to communicate with another (more specific) without intimate knowledge of its implementation. It is an idea basically, and an “abstract” one in some sense.

There is a couple of concrete techniques that implement the IoC principle: callbacks, interface dispatch, dynamic call dispatch, virtual calls etc. One could remember typeclasses from Haskell. Even an abstract factory pattern may be seen as some sort of IoC, as it gives its client ability to construct instances of product without knowing its concrete class.

Sure, frameworks are using IoC almost always, but IoC doesn’t implies a framework by itself. When you call Win32 API function that takes a callback – you’re using IoC without any framework involved.

Now, Dependency Injection is one of aspects that allow to achieve IoC: if some code creates its dependencies itself (e.g. with direct calls of their constructors) – it definitely can’t be unknowing about details of their implementation. It knows precise type – indeed a very strong variant of coupling. Injecting such dependencies instead by some external entity is what implements IoC principle here. In other words, DI is one possible technique to achieve IoC.

IoC-container is a piece of software that allows applying and reusing different IoC techniques in your code. Usually a library. For example, Windsor container supports several types of DI, automatic typed implementation of abstract factories and some more. And with all of that it is obviously a pure library, not a framework.

Hence, IoC-container as a term is not “meaningless”. I’d rather say that defining IoC as key difference between library and framework is meaningless.

Finally, Dependency Inversion Principle is a guidance that dictates which is the most promising way to structure software. Namely, higher levels of abstraction should not depend on lower levels. For example, module responsible for publishing reports should not depend on sockets to send them. It is easy to imagine sending reports via email, file, web-service, printing or RSS, as well as formatting them in dozen of formats. Having knowledge about such low-level details makes code likely candidate for rewriting later.

25/12/2012

EnumerateChain extension method

Filed under: c#, patterns — Ivan Danilov @ 19:12

Very small, simple and extremely useful method:

        public static IEnumerable<T> EnumerateChain<T>(this T start, Func<T, T> next)
            where T : class
        {
            while (start != null)
            {
                yield return start;
                start = next(start);
            }
        }

How to use it you may ask. Suppose (just for the sake of example) you have some tree structure, with Name and Parent properties in each node. And you want to get path in tree of some given node in form of node names separated by slashes. Nothing could be easier:

public static string GetPathInTree(Node node)
{
    var names = node.EnumerateChain(n => n.Parent).Reverse().Select(n => n.Name);
    return String.Join("/", names);
}

Basically with this method you can traverse any structure as if it was normal IEnumerable. Very convenient, really 🙂

16/08/2012

Weakly referenced Decorator: meet the ephemerons in .NET

Filed under: patterns — Ivan Danilov @ 01:07

Sometimes we have long-living class that should notify other classes with potentially short lifetime about some event. In such case WeakReference is the obvious solution to prevent memory leaks. Well, something like that, supposing long-lived class named Service and short-living is Client (for simplicity sake I’ve limited Service‘s handling abilities to just one client):

    public interface IClient {
        void Notify();
    }

    public class Service {
        private WeakReference _clientRef;

        public void AddClient(IClient client) {
            _clientRef = new WeakReference(client);
        }

        public void NotifyClientIfAlive() {
            var client = (IClient)_clientRef.Target;
            if (client != null) client.Notify();
        }
    }

    public class Client : IClient {
        public void Notify() { /* not important */ }
    }

So far, so good. You’ve wrote such code and it’s working beautifully. But now yet one task comes: suppose it is logging, or something similar and you decide to implement that via the Decorator pattern. Well, it is very handy we have that IClient interface, isn’t it? Just a piece of cake:

    public class ClientDecorator : IClient {
        private readonly IClient _realClient;

        public ClientDecorator(IClient realClient) {
            _realClient = realClient;
        }

        public void Notify() {
            // do what is needed
            _realClient.Notify();
        }
    }

Now we can just pass instance of ClientDecorator to the Service and be off.
Well, not really. If you will construct IClient just from the start with decorator and work with decorated instance all the time – it is ok.
But what if you want to implement decoration of calls from this service only? Or, you receive already-made instance of IClient from somewhere. Then you have a problem: if you wrap your instance and ‘forget’ strong reference to newly created decorator – it would be garbage collected at the very next GC pass. Moreover, it will break not only your logging, but the message will never reach real client in the first place. Let me illustrate the problem with small unit test:

        [Test]
        public void DecoratorIsNotGCedWhenRefsToRealClientExist() {
            var client = new Client();
            var decorator = new ClientDecorator(client);
            var service = new Service();
            service.AddClient(decorator);

            // create weak refs to watch if these are alive
            var weakClient = new WeakReference(client);
            var weakDecorator = new WeakReference(decorator);

            // nullify strong ref to decorator, but leave to client
            decorator = null;

            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            Assert.IsTrue(weakClient.IsAlive);
            Assert.IsTrue(weakDecorator.IsAlive);
        }

Oops. Red test. Not good. Well, of course, we could have made Service‘s refs strong, but than both client and decorator will live at least as long as the Service, i.e. we will introduce memory leak this way. Let’s write another unit test and requirement:

        [Test]
        public void ClientDecoratorIsGCedWhenNoClientRefsAreAlive() {
            var client = new Client();
            var decorator = new ClientDecorator(client);
            var service = new Service();
            service.AddClient(decorator);

            // create weak refs to watch if these are alive
            var weakClient = new WeakReference(client);
            var weakDecorator = new WeakReference(decorator);

            // nullify strong refererences
            client = null;
            decorator = null;

            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            Assert.IsFalse(weakClient.IsAlive);
            Assert.IsFalse(weakDecorator.IsAlive);
        }

It is almost the same except that both strong refs to decorator and client dying, and after GC – they should be swept, simulating client death when service is still alive and demonstrating that no memory leaks is present.

Another option is to make service aware of decorator’s presence: then service can have strong ref to decorator and weak – to real client, decorator will have weak reference to client and when notification is there – service can check real client and remove decorator as well. It is complex even to read, not only to understand. And totally defeats purpose of decorator. And if you will have to add two, three or four decorators to the single client… oops, you have a real problem in this case with such an approach.

So, can we do better? Yes, we can. What we need is to invent a way to keep decorator’s instance alive not as long as someone have strong refs to itself, but as long as someone have strong refs to other instance, namely to real client instance. That task is precise description of ephemeron. Since .NET 4.0 they are supported by CLR in the form of ConditionalWeakTable<TKey, TValue> class.

Here is the code:

    public class ClientDecorator : IClient {
        private static readonly ConditionalWeakTable<IClient, ClientDecorator> _keepaliveMap = new ConditionalWeakTable<IClient, ClientDecorator>();
        private readonly IClient _realClient;

        public ClientDecorator(IClient realClient) {
            _realClient = realClient;
            _keepaliveMap.Add(realClient, this);
        }

        public void Notify() {
            // do what is needed
            _realClient.Notify();
        }
    }

Basically adding to _keepaliveMap is equivalent to making this instance non-eligible for GC while realClient is not going to be GCed.

Both tests are green, hooray! But we can do even better, we can move out required logic to base class and enable any decorator to use it without code duplication, like that:

    public class WeaklyReferencedDecorator<T> where T : class {
        private static readonly ConditionalWeakTable<T, WeaklyReferencedDecorator<T>> _keepaliveMap = new ConditionalWeakTable<T, WeaklyReferencedDecorator<T>>();
        protected readonly T Instance;

        public WeaklyReferencedDecorator(T instance) {
            Instance = instance;
            _keepaliveMap.Add(instance, this);
        }
    }

    public class ClientDecorator : WeaklyReferencedDecorator<IClient>, IClient {
        public ClientDecorator(IClient realClient) : base(realClient) {}

        public void Notify() {
            // do what is needed
            Instance.Notify();
        }
    }

It seems, with base class amount of code… huh, LOCs number even decreased as we have Instance variable on base class now. Looks good, isn’t it?

Just to be sure everything is OK, lets write tests to simulate several stacking decorators one on top of another:

        [Test]
        public void StackingTwoDecoratorsGCedCorrectly() {
            var client = new Client();
            var service = new Service();
            var clientDecorator1 = new ClientDecorator(client);
            var clientDecorator2 = new ClientDecorator(clientDecorator1);
            service.AddClient(clientDecorator2);

            var weakDecorator1 = new WeakReference(clientDecorator1);
            var weakDecorator2 = new WeakReference(clientDecorator1);
            var weakClient = new WeakReference(client);
            clientDecorator1 = clientDecorator2 = null;
            client = null;

            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            Assert.IsFalse(weakClient.IsAlive);
            Assert.IsFalse(weakDecorator1.IsAlive);
            Assert.IsFalse(weakDecorator2.IsAlive);
        }

        [Test]
        public void StackingTwoDecoratorsNotGCedIfRefToRealClientExist() {
            var client = new Client();
            var service = new Service();
            var clientDecorator1 = new ClientDecorator(client);
            var clientDecorator2 = new ClientDecorator(clientDecorator1);
            service.AddClient(clientDecorator2);

            var weakDecorator1 = new WeakReference(clientDecorator1);
            var weakDecorator2 = new WeakReference(clientDecorator1);
            var weakClient = new WeakReference(client);
            clientDecorator1 = clientDecorator2 = null;

            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            Assert.IsTrue(weakClient.IsAlive);
            Assert.IsTrue(weakDecorator1.IsAlive);
            Assert.IsTrue(weakDecorator2.IsAlive);
        }

All of the tests pass, so it seems we’re done.

And a last word about where it could be possibly useful except mentioned scenario with some notifying service (which will probably have a collection of WeakReference’s is real world). Here is my answer to related question. In short, with addition of collectible assemblies for dynamic type generation in .NET 4.0, you can’t safely cache reflection data in something alike Dictionary<Type, MyReflectionResult> because doing so will prevent GC from collecting such dynamic types even if no one needs them anymore because your cache will keep them alive. Bad thing, especially if you’re writing some general-purpose lib or framework.

Hope this post was interesting to someone 🙂

Blog at WordPress.com.