Whilst working on my network engine I came across a problem that I initially solved with an interface, but it turned out that the class that implemented this interface exposed public methods that I really wanted to be private, an example will explain the problem.
public interface IMessageReceiver { void Receive(string message); } public interface IMessageProvider { IMessageReceiver MessageReceiver; void Update(); } public class ConcreteReceiver: IMessageReceiver { private IMessageProvider _MessageProvider; public ConcreteReciever(IMessageProvider messageProvider) { _MessageProvider = messageProvider; _MessageProvider.MessageReceiver = this; } public void Receive(string message) { Console.WriteLine(message); } public void Update() { MessageProvider.Update(); } }
When calling ConcreteReceiver.Update(), this will call MessageProvider.Update(), then, the concrete implementation of IMessageProvider should call IMessageReceiver.Receive, effectively like a callback.Now the issue in my case was that I did not want the Receive method of ConcreteReceiver to be public, but of course any concrete type that implements an interface must implement those methods as public, after pondering a while I realised the design was actually flawed anyway, what I really wanted was a callback, so I changed my design as follows.
public interface IMessageProvider { Action<string> ReceiveAction; void Update(); } public class ConcreteReceiver { private IMessageProvider _MessageProvider; public ConcreteReciever(IMessageProvider messageProvider) { _MessageProvider = messageProvider; _MessageProvider.ReceiveAction = Receive; } private void Receive(string message) { Console.WriteLine(message); } public void Update() { MessageProvider.Update(); } }
So now my Receive method on my ConcreteReceiver can be private, since I am now using a generic Action<T> delegate, this prevents my public API exposing methods that are really meant to be only used internally.
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.