mercredi 28 novembre 2018

Composing a common interface with c# library class

Suppose I have a class:

public class Foo<TKey, TValue> {
    private readonly ConcurrentDictionary<TKey, TValue> m_dict;
    public Foo() {
        m_dict = new ConcurrentDictionary<TKey, TValue>();
    }
    public void AddThings(TKey key, TValue val) {
        m_dict.Add(key, val);
    }
    public void RemoveThings(TKey key) {
        m_dict.Remove(key);
    }
    //}

This is the API for ConcurrentDictionary : https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2?view=netframework-4.7.2 It implements the following interfaces:

public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IDictionary, ICollection, IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>

Essentially my class Foo uses a subset of ConcurrentDictionary's API methods.

Now there is a requirement to use a ConcurrentTreeMap<TKey, TValue> in the client class in certain use cases. I have implemented a ConcurrentTreeMap<TKey, TValue> class myself with all the API methods the client class is requiring. This class implements IDictionary<TKey, TValue> and ICollection<KeyValuePair<TKey, TValue>>

I want my Foo client class to be able to use both ConcurrentDictionary and ConcurrentTreeMap. Something like this, simplified:

public class Foo<TKey, TValue> {
        private readonly IConcurrentDictionary<TKey, TValue> m_dict;
        public Foo(IConcurrentDictionary dict) {
            m_dict = dict;
        }
        public void AddThings(TKey key, TValue val) {
            m_dict.Add(key, val);
        }
        public void RemoveThings(TKey key) {
            m_dict.Remove(key);
        }
        //}

This would be easy for languages like Python and Go. If I had access to ConcurrentDictionary's implementation I would obviously just extract a common interface type between the two. Or I could define a composite interface of all the interfaces ConcurrentDictionary implements. But since ConcurrentDictionary is part of some base c# library, I can't do that. Should I use some type of proxy class between ConcurrentDictionary and my custom interface? That seems like a lot of boilerplate code I'd have to write.

The backing data between a treemap and a hashmap(dictionary) is quite different so I also couldn't inherit ConcurrentTreeMap from ConcurrentDictionary (most of its methods are not virtual, anyways).

Aucun commentaire:

Enregistrer un commentaire