Making a web service call based on a type of request I have my code which makes a web service call based on a type of request:

public class Client
{
    IRequest request;


    public Client(string requestType)
    {
        request = new EnrolmentRequest();
        if (requestType == "Enrol")
        {
            request.DoEnrolment();
        }
        else if (requestType == "ReEnrol")
        {
            request.DoReEnrolment();
        }
        else if (requestType == "DeleteEnrolment")
        {
            request.DeleteEnrolment();
        }
        else if (requestType == "UpdateEnrolment")
        {
            request.UpdateEnrolment();
        }
    }

}


So as per open close principle, I can subclass like:

Class EnrolmentRequest:IRequest
{
    CallService();
}
Class ReEnrolmentRequest:IRequest
{
    CallService();
}
Class UpdateEnrolmentRequest:IRequest
{
    CallService();
}


Now my client class will look something like this:

public class Client
{
    public Client(string requestType)
    {
        IRequest request;

        if (requestType == "Enrol")
        {
            request = new EnrolmentRequest();
            request.CallService();
        }
        else if (requestType == "ReEnrol")
        {
            request = new REnrolmentRequest();
            request.CallService();
        }
        else if (requestType == "DeleteEnrolment")
        {
            request = new UpdateEnrolmentRequest();
            request.CallService();
        }
        else if (requestType == "UpdateEnrolment")
        {
            request = new UpdateEnrolmentRequest();
            request.CallService();
        }
    }

}


Now, I still have to use if and else, and will have to change my code if there are any new request type. So, it's definitely, not closed to modification.

Am I missing anything with respect to SOLID?
It would be better to give the Irequest interface an additional "Name" property that returns the value of requestType. Than you can iterate over all Irequest implementations and get the first with the corresponding name ;).

Example:

interface IRequest
{
    void CallService();
    string Name { get; }
}
class EnrolmentRequest : IRequest
{
    public void CallService() { /* impl. */ }
    public string Name =&gt; "Enrol";

}
class ReEnrolmentRequest : IRequest
{
    public void CallService() { /* impl. */ }
    public string Name =&gt; "ReEnrol";
}

...

public class Client
{
    private static IRequest[] requestHandlers = new IRequest[] 
    {
        new EnrolmentRequest(),
        new ReEnrolmentRequest(),
        ...
    }

    public Client(string requestType)
    {
        IRequest request = requestHandlers.SingleOrDefault(x =&gt; x.Name == requestType);
        if (request == null) { /* Handle null case */ }

        request.CallService();
    }    
}


That code fulfills the open/closed principle because you can add new request handlers without modified existing logic.