I have a method that accepts an interface and does type checking on the parameter, and depending upon the type a decision is made to either send an email or an alert    public void Bar(ISomeInterface someClass)    {        if (someClass is SomeClassToo)        {            Emailer.Send(someClass.Something());        }        else        {            Alerter.Alert(someClass.Something());        }    }I know this is bad for obvious reasons, but I would like to know what other options I have to resolve this, as one of the solutions I have is to put an abstraction on each of the classes that implements ISomeInterface for the emailer/alerter using an ICommunicator (see below) but I am not sure that is right as it feels like somewhere in my code there will have to be something that checks the type or knows about each type even if it is just in an IOC container configuration.public class SomeClass : ISomeInterface{    private ICommunicator _communicator;    public SomeClass(ICommunicator communicator)    {        _communicator = communicator;    }    public void Something()    {        if (_communicator != null)        {            _communicator.Send(yee ha);        }    }
Fix a leaky abstraction (type checking)
c#;design;object oriented;abstraction
Without the full context it's hard to know the right thing to do.It seems to me though that the ISomeInterface implementers need to do something differently, depending on the implementation.  That leads me to believe that your second approach is correct.The thing is, each ISomeInterface implementation can have its own list of dependencies.  One could take an Alerter while another could take an Emailer.  So long as a third party class could call ISomeInterface.Something() without needing to know anything about whether Something() is calling an Emailer or an Alerter or a SkynetActivatoryou're set.  When SomeClass is constructed, something will need to know which dependencies to provide to it, but that's ok, because it's a concrete class.Concrete classes are allowed to have dependencies.  Interfaces should not be dependent on implementation.