Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# interface design, expose library classes?

I want to define an interface "IFile" that includes an array of key/value pairs "Metadata". When getting or setting these key/value pairs, the IFile implementor should be able to take action. What would be the best way to go about this? I see three methods:

Method 1) Get/Set a dictionary object:

public interface IFile
{
    ...

    Dictionary<String, String> GetMetadata();

    void SetMetadata(Dictionary<String, String> metadata);
}

Method 2) Use a Dictionary class directly:

public interface IFile
{
    ...

    Dictionary Metadata();
}

and in the implementation of IFile, an inherited version of Dictionary could be provided that acts on get / set.

Method 3) Avoid Dictionary altogether and provide a custom interface, for instance:

public interface IMetadata
{
    String GetValue(String key);        
    void SetValue(String key, String value);        
    Boolean Contains(String key);        
    void Delete(String key);  

    ...
}

public interface IFile
{
    ...

    IMetadata Metadata();
}

I lean towards method 3 because it lets the implementor decide how to actually implement the metadata data structure. The other solutions force the use of a Dictionary. However method 3 seems to involve a lot of extra wrapping code.

I sense that behind this question there is a deeper rooted dilemma when designing class hierarchies, which is whether to expose library classes directly or to expose a few wrapped functions that hides an internally used library class. I have little actual experience in making OOP designs, so advice on what the "Right Way" is in this regard would be very welcome!

Thanks,

Lars

like image 409
Larsp Avatar asked Apr 01 '26 17:04

Larsp


2 Answers

If the type of the metadata is known at compile time, then personally I would probably go for this:

public interface IFile
{
    ...

    IDictionary<string, string> Metadata { get; }
}

Note - IDictionary instead of Dictionary - that leaves it up to the implementing class as to what type of dictionary implementation to use.

(I used string for the dictionary type as an example and also because that's the type you used for IMetadata - change to fit your needs if necessary)

ps - If the range of keys for the metadata is fixed and relatively small, then make the key an enum - that's more efficient than string comparisons.

like image 162
Nathan Avatar answered Apr 04 '26 07:04

Nathan


I like option 3 (defining the methods in the interface), because:

  1. It doesn't force the implementation to use a particular data structure.
  2. It is more testable/mock-able.
like image 23
CodingWithSpike Avatar answered Apr 04 '26 06:04

CodingWithSpike



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!