Composing a common interface with c# library class





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















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).










share|improve this question























  • Im guessing you want thread safety here, just be very careful with this type of thing, you could easily get the thread safety aspect wrong

    – Michael Randall
    Nov 29 '18 at 1:34


















1















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).










share|improve this question























  • Im guessing you want thread safety here, just be very careful with this type of thing, you could easily get the thread safety aspect wrong

    – Michael Randall
    Nov 29 '18 at 1:34














1












1








1








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).










share|improve this question














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).







c# oop design-patterns dependency-injection interface






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 29 '18 at 1:29









user3805884user3805884

507




507













  • Im guessing you want thread safety here, just be very careful with this type of thing, you could easily get the thread safety aspect wrong

    – Michael Randall
    Nov 29 '18 at 1:34



















  • Im guessing you want thread safety here, just be very careful with this type of thing, you could easily get the thread safety aspect wrong

    – Michael Randall
    Nov 29 '18 at 1:34

















Im guessing you want thread safety here, just be very careful with this type of thing, you could easily get the thread safety aspect wrong

– Michael Randall
Nov 29 '18 at 1:34





Im guessing you want thread safety here, just be very careful with this type of thing, you could easily get the thread safety aspect wrong

– Michael Randall
Nov 29 '18 at 1:34












1 Answer
1






active

oldest

votes


















2














Foo<TKey, TValue> is essentially a wrapper around a collection. If you want a wrapper around a different collection, then possibly the best approach would be to create an interface:



public interface IFoo<TKey, TValue>
{
void AddThings(TKey key, TValue val);
void RemoveThings(TKey key);
}


...and have two separate implementations of it - one using an inner ConcurrentDictionary and the other using your ConcurrentTreeMap<TKey, TValue>.



Here's one implementation - I don't know the other because I don't have your ConcurrentTree class:



public class ConcurrentDictionaryFoo : IFoo<TKey, TValue>
{
private readonly ConcurrentDictionary<TKey, TValue> _dictionary
= new ConcurrentDictionary<TKey, TValue>();

void AddThings(TKey key, TValue val)
{
_dictionary.TryAdd(key, val);
}

void RemoveThings(TKey key)
{
_dictionary.TryRemove(key);
}
}


That's the most common practice when we have one interface and multiple implementations. We wouldn't normally try to put both implementations in one class.



You could put them both in one class. You could have both a ConcurrentDictionary and a ConcurrentTreeMap within one class, and then maybe some flag in the constructor would tell the class which inner collection it should use.



But if we follow where that leads, what happens if you need another implementation that uses a different collection, and another, and another? That's an easy problem to solve if you're creating distinct implementations of IFoo, but it would be complex and messy if you tried to put all possible implementations in a single class.



What if this class is complex and the collection is just one small part of it, and you don't want to duplicate the rest of the code just because you want it to work with either collection type?



In that case you would still create an interface to represent the collection, and have separate implementations for ConcurrentDictionary and ConcurrentTreeMap. Then Foo would depend on that abstraction, and not on either concrete collection. Something like this:



public class Foo<TKey, TValue>
{
private readonly IFooDictionary<TKey, TValue> _dictionary;

public Foo(IFooDictionary<TKey, TValue> dictionary)
{
_dictionary = dictionary;
}
}


Now Foo just depends on IFooDictionary and doesn't know if the underlying implementation is a ConcurrentDictionary or a ConcurrentTreeMap.



This somewhat lines up with what you said:




If I had access to ConcurrentDictionary's implementation I would obviously just extract a common interface type between the two.




Except that common interface isn't something you extract - it's something you create. You define the interface that describes what your other classes need to use this thing for. Then you just create an adapter or wrapper around the ConcurrentDictionary or ConcurrentTreeMap which directs the methods of the interface to the correct methods of the inner collection - just like in the example above where the AddThings method calls the TryAdd method of the inner dictionary.






share|improve this answer


























  • right, this is similar to the facade or wrapper

    – Chris Hayes
    Nov 29 '18 at 5:45












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53530570%2fcomposing-a-common-interface-with-c-sharp-library-class%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














Foo<TKey, TValue> is essentially a wrapper around a collection. If you want a wrapper around a different collection, then possibly the best approach would be to create an interface:



public interface IFoo<TKey, TValue>
{
void AddThings(TKey key, TValue val);
void RemoveThings(TKey key);
}


...and have two separate implementations of it - one using an inner ConcurrentDictionary and the other using your ConcurrentTreeMap<TKey, TValue>.



Here's one implementation - I don't know the other because I don't have your ConcurrentTree class:



public class ConcurrentDictionaryFoo : IFoo<TKey, TValue>
{
private readonly ConcurrentDictionary<TKey, TValue> _dictionary
= new ConcurrentDictionary<TKey, TValue>();

void AddThings(TKey key, TValue val)
{
_dictionary.TryAdd(key, val);
}

void RemoveThings(TKey key)
{
_dictionary.TryRemove(key);
}
}


That's the most common practice when we have one interface and multiple implementations. We wouldn't normally try to put both implementations in one class.



You could put them both in one class. You could have both a ConcurrentDictionary and a ConcurrentTreeMap within one class, and then maybe some flag in the constructor would tell the class which inner collection it should use.



But if we follow where that leads, what happens if you need another implementation that uses a different collection, and another, and another? That's an easy problem to solve if you're creating distinct implementations of IFoo, but it would be complex and messy if you tried to put all possible implementations in a single class.



What if this class is complex and the collection is just one small part of it, and you don't want to duplicate the rest of the code just because you want it to work with either collection type?



In that case you would still create an interface to represent the collection, and have separate implementations for ConcurrentDictionary and ConcurrentTreeMap. Then Foo would depend on that abstraction, and not on either concrete collection. Something like this:



public class Foo<TKey, TValue>
{
private readonly IFooDictionary<TKey, TValue> _dictionary;

public Foo(IFooDictionary<TKey, TValue> dictionary)
{
_dictionary = dictionary;
}
}


Now Foo just depends on IFooDictionary and doesn't know if the underlying implementation is a ConcurrentDictionary or a ConcurrentTreeMap.



This somewhat lines up with what you said:




If I had access to ConcurrentDictionary's implementation I would obviously just extract a common interface type between the two.




Except that common interface isn't something you extract - it's something you create. You define the interface that describes what your other classes need to use this thing for. Then you just create an adapter or wrapper around the ConcurrentDictionary or ConcurrentTreeMap which directs the methods of the interface to the correct methods of the inner collection - just like in the example above where the AddThings method calls the TryAdd method of the inner dictionary.






share|improve this answer


























  • right, this is similar to the facade or wrapper

    – Chris Hayes
    Nov 29 '18 at 5:45
















2














Foo<TKey, TValue> is essentially a wrapper around a collection. If you want a wrapper around a different collection, then possibly the best approach would be to create an interface:



public interface IFoo<TKey, TValue>
{
void AddThings(TKey key, TValue val);
void RemoveThings(TKey key);
}


...and have two separate implementations of it - one using an inner ConcurrentDictionary and the other using your ConcurrentTreeMap<TKey, TValue>.



Here's one implementation - I don't know the other because I don't have your ConcurrentTree class:



public class ConcurrentDictionaryFoo : IFoo<TKey, TValue>
{
private readonly ConcurrentDictionary<TKey, TValue> _dictionary
= new ConcurrentDictionary<TKey, TValue>();

void AddThings(TKey key, TValue val)
{
_dictionary.TryAdd(key, val);
}

void RemoveThings(TKey key)
{
_dictionary.TryRemove(key);
}
}


That's the most common practice when we have one interface and multiple implementations. We wouldn't normally try to put both implementations in one class.



You could put them both in one class. You could have both a ConcurrentDictionary and a ConcurrentTreeMap within one class, and then maybe some flag in the constructor would tell the class which inner collection it should use.



But if we follow where that leads, what happens if you need another implementation that uses a different collection, and another, and another? That's an easy problem to solve if you're creating distinct implementations of IFoo, but it would be complex and messy if you tried to put all possible implementations in a single class.



What if this class is complex and the collection is just one small part of it, and you don't want to duplicate the rest of the code just because you want it to work with either collection type?



In that case you would still create an interface to represent the collection, and have separate implementations for ConcurrentDictionary and ConcurrentTreeMap. Then Foo would depend on that abstraction, and not on either concrete collection. Something like this:



public class Foo<TKey, TValue>
{
private readonly IFooDictionary<TKey, TValue> _dictionary;

public Foo(IFooDictionary<TKey, TValue> dictionary)
{
_dictionary = dictionary;
}
}


Now Foo just depends on IFooDictionary and doesn't know if the underlying implementation is a ConcurrentDictionary or a ConcurrentTreeMap.



This somewhat lines up with what you said:




If I had access to ConcurrentDictionary's implementation I would obviously just extract a common interface type between the two.




Except that common interface isn't something you extract - it's something you create. You define the interface that describes what your other classes need to use this thing for. Then you just create an adapter or wrapper around the ConcurrentDictionary or ConcurrentTreeMap which directs the methods of the interface to the correct methods of the inner collection - just like in the example above where the AddThings method calls the TryAdd method of the inner dictionary.






share|improve this answer


























  • right, this is similar to the facade or wrapper

    – Chris Hayes
    Nov 29 '18 at 5:45














2












2








2







Foo<TKey, TValue> is essentially a wrapper around a collection. If you want a wrapper around a different collection, then possibly the best approach would be to create an interface:



public interface IFoo<TKey, TValue>
{
void AddThings(TKey key, TValue val);
void RemoveThings(TKey key);
}


...and have two separate implementations of it - one using an inner ConcurrentDictionary and the other using your ConcurrentTreeMap<TKey, TValue>.



Here's one implementation - I don't know the other because I don't have your ConcurrentTree class:



public class ConcurrentDictionaryFoo : IFoo<TKey, TValue>
{
private readonly ConcurrentDictionary<TKey, TValue> _dictionary
= new ConcurrentDictionary<TKey, TValue>();

void AddThings(TKey key, TValue val)
{
_dictionary.TryAdd(key, val);
}

void RemoveThings(TKey key)
{
_dictionary.TryRemove(key);
}
}


That's the most common practice when we have one interface and multiple implementations. We wouldn't normally try to put both implementations in one class.



You could put them both in one class. You could have both a ConcurrentDictionary and a ConcurrentTreeMap within one class, and then maybe some flag in the constructor would tell the class which inner collection it should use.



But if we follow where that leads, what happens if you need another implementation that uses a different collection, and another, and another? That's an easy problem to solve if you're creating distinct implementations of IFoo, but it would be complex and messy if you tried to put all possible implementations in a single class.



What if this class is complex and the collection is just one small part of it, and you don't want to duplicate the rest of the code just because you want it to work with either collection type?



In that case you would still create an interface to represent the collection, and have separate implementations for ConcurrentDictionary and ConcurrentTreeMap. Then Foo would depend on that abstraction, and not on either concrete collection. Something like this:



public class Foo<TKey, TValue>
{
private readonly IFooDictionary<TKey, TValue> _dictionary;

public Foo(IFooDictionary<TKey, TValue> dictionary)
{
_dictionary = dictionary;
}
}


Now Foo just depends on IFooDictionary and doesn't know if the underlying implementation is a ConcurrentDictionary or a ConcurrentTreeMap.



This somewhat lines up with what you said:




If I had access to ConcurrentDictionary's implementation I would obviously just extract a common interface type between the two.




Except that common interface isn't something you extract - it's something you create. You define the interface that describes what your other classes need to use this thing for. Then you just create an adapter or wrapper around the ConcurrentDictionary or ConcurrentTreeMap which directs the methods of the interface to the correct methods of the inner collection - just like in the example above where the AddThings method calls the TryAdd method of the inner dictionary.






share|improve this answer















Foo<TKey, TValue> is essentially a wrapper around a collection. If you want a wrapper around a different collection, then possibly the best approach would be to create an interface:



public interface IFoo<TKey, TValue>
{
void AddThings(TKey key, TValue val);
void RemoveThings(TKey key);
}


...and have two separate implementations of it - one using an inner ConcurrentDictionary and the other using your ConcurrentTreeMap<TKey, TValue>.



Here's one implementation - I don't know the other because I don't have your ConcurrentTree class:



public class ConcurrentDictionaryFoo : IFoo<TKey, TValue>
{
private readonly ConcurrentDictionary<TKey, TValue> _dictionary
= new ConcurrentDictionary<TKey, TValue>();

void AddThings(TKey key, TValue val)
{
_dictionary.TryAdd(key, val);
}

void RemoveThings(TKey key)
{
_dictionary.TryRemove(key);
}
}


That's the most common practice when we have one interface and multiple implementations. We wouldn't normally try to put both implementations in one class.



You could put them both in one class. You could have both a ConcurrentDictionary and a ConcurrentTreeMap within one class, and then maybe some flag in the constructor would tell the class which inner collection it should use.



But if we follow where that leads, what happens if you need another implementation that uses a different collection, and another, and another? That's an easy problem to solve if you're creating distinct implementations of IFoo, but it would be complex and messy if you tried to put all possible implementations in a single class.



What if this class is complex and the collection is just one small part of it, and you don't want to duplicate the rest of the code just because you want it to work with either collection type?



In that case you would still create an interface to represent the collection, and have separate implementations for ConcurrentDictionary and ConcurrentTreeMap. Then Foo would depend on that abstraction, and not on either concrete collection. Something like this:



public class Foo<TKey, TValue>
{
private readonly IFooDictionary<TKey, TValue> _dictionary;

public Foo(IFooDictionary<TKey, TValue> dictionary)
{
_dictionary = dictionary;
}
}


Now Foo just depends on IFooDictionary and doesn't know if the underlying implementation is a ConcurrentDictionary or a ConcurrentTreeMap.



This somewhat lines up with what you said:




If I had access to ConcurrentDictionary's implementation I would obviously just extract a common interface type between the two.




Except that common interface isn't something you extract - it's something you create. You define the interface that describes what your other classes need to use this thing for. Then you just create an adapter or wrapper around the ConcurrentDictionary or ConcurrentTreeMap which directs the methods of the interface to the correct methods of the inner collection - just like in the example above where the AddThings method calls the TryAdd method of the inner dictionary.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 29 '18 at 2:23

























answered Nov 29 '18 at 1:56









Scott HannenScott Hannen

13.3k1426




13.3k1426













  • right, this is similar to the facade or wrapper

    – Chris Hayes
    Nov 29 '18 at 5:45



















  • right, this is similar to the facade or wrapper

    – Chris Hayes
    Nov 29 '18 at 5:45

















right, this is similar to the facade or wrapper

– Chris Hayes
Nov 29 '18 at 5:45





right, this is similar to the facade or wrapper

– Chris Hayes
Nov 29 '18 at 5:45




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53530570%2fcomposing-a-common-interface-with-c-sharp-library-class%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

Calculate evaluation metrics using cross_val_predict sklearn

Insert data from modal to MySQL (multiple modal on website)