I have a socket communication subsystem accessible by SocketContext facade, the only public class in class library. SocketContext allows you to connect to remote endpoind, send and receive messages.
The problem is following: let’s say SocketContext consumer wants to monitor sent messages queue (send process is asynchronous).
Well, we need to add int QueueSize {get;} property in SocketContext but what happens next is we are going to find who is aware of queue size and it is a DataSocket class that SocketContext is not aware of, so to pull that property to SocketContext i have to wrap it multiple times like this:
// DataSocket -> Connection -> SocketClient -> SocketContext
internal class DataSocket
{
public int QueueSize { get{ /* calculating and returning actual value */ }}
}
internal class Connection
{
IDataSocket _dataSocket;
int QueueSize { get{ return _dataSocket.QueueSize; }}
}
internal class SocketClient
{
IConnection _connection;
int QueueSize { get{ return _connection.QueueSize; }}
}
public class SocketContext
{
ISocketClient _client;
int QueueSize { get{ return _client.QueueSize; }}
}
What am i doing wrong?
I would say this could be one of the first problems. if there is only 1 public component then it makes it very difficult to expose functionality. This also fails concepts like single responsibility, open/closed design and interface segregation. you basically have 1 object doing everything.
There may be a single access point like the
SocketContextFacade, but that is how you enter the API which can then expose other objects/components the client can interact with.Alot of 3rd party libraries I use usually have 2 aspects to them.
Configuration happens once, at start up. It tells the library how to behave for your particular needs. The runtime is used throughout the system, behaving according to the configuration. Here are some examples: