0

There are two different services. Those services have different processes but give us same result. A helper method needs to use that services and service responses. User is going to choose the which service will using. So, I am going to create a helper method and it takes chosen service and its parameters. The problem is that services need different parameters with different size.(a few of them is common but not most of them)

I create an abstract class and then two class inherited from it. Abstract class contains an standart method. But inherited class methods needs different type and size parameters. Because of that, I planning to use dynamic class object as a parameter. Is that proper solution?

public abstract class ServiceBase
{
    public abstract int StandartMethod(dynamic parameters);
}

public class ServiceForA : ServiceBase
{
    public override int StandartMethod(dynamic parameters)
    {
        //Service Request is send to ServiceA with spesific parameters
        //(parameters.Ticket, parameter.myType1, string p1 , int n1, ..)
        //----
        //Service Response received and processed
        return requiredInfo;
    }
}

public class ServiceForB : ServiceBase
{
    public override int StandartMethod(dynamic parameters)
    {
        //Service Request is send to ServiceB with spesific parameters
        //(parameters.UserName,parameters.Password, parameters.myType1,int beginRange, ..)
        //----
        //Service Response received and processed
        return requiredInfo;
    }
}

public static int HelperMethod(ServiceBase service, ServiceParameters parameters)
{
   //Do required stuff
   return service.StandartMethod(parameters);
}

static void Main(string[] args)
        {
            ServiceBase serviceA = new ServiceForA();

            dynamic obj1 = new ServiceParameters();

            obj1.Ticket = GetTicket(UserName,Pass);
            obj1.p1 = "Parameter1";
            obj1.n1 = 10;

            var result = HelperMethod(serviceA, obj1);

            Console.WriteLine("RESULT 1: " + result);

            ServiceBase serviceB = new ServiceForB();

            dynamic obj2 = new ServiceParameters();
            obj2.UserName = "slyn";
            obj2.Password = "****";
            ...
            obj2.beginRange = 1;


            var result2 = HelperMethod(serviceB, obj2);

            Console.WriteLine("RESULT2: " + result2);

        }

Service object type will be ServiceForA or ServiceForB. It doesn't matter, StandartMethod is implemented both classes. And ServiceParameters class is inherited from System.Dynamic.DynamicObject

It seems solve the problem, but is it proper solution? Any suggestion?

3
  • No, you check the type using the is operator and then cast the class to the concrete type and modify its parameters. Commented Apr 1, 2017 at 9:52
  • 1
    If I delete dynamic parameters from method definition, there will not be abstract class anymore (overrided abstract methods needs same parameters). I need to write actual parameters in method definition.(In our example, ServiceForA and ServiceForB are not inheried from ServiceBase and StandartsMethods take params in ServiceFor* classes.) After that why do I need cast class and modify parameters? Commented Apr 1, 2017 at 11:13
  • Hi @john, My base problem is one abstract method sould be implemented with different parameters. Is there any way to implementation that kind of? Commented Apr 1, 2017 at 11:19

2 Answers 2

1

Usually you end up using generics for this:

public abstract class ServiceBase<TArgs>
{
    public abstract int StandardMethod(TArgs args);
}

public class Arguments
{
     public string Text { get; set; }
     public int Number { get; set; }
}

public class ServiceForB : ServiceBase<Arguments>
{
    public override int StandardMethod(Arguments arguments)
    {
        // Thanks to generics, arguments are strongly-typed and
        // and you can access its properties as usual!
        string text = arguments.Text;
        int number = arguments.Number;

        return 0;
    }
}

BTW this approach has a possible problem: what if you need another method as part of the abstract class to support the same scenario? You would end up with many generic type parameters for each of them. Anyway, as you stated that your issue is just with one method, this should work fine.

Sign up to request clarification or add additional context in comments.

Comments

1

using Strategy pattern at run time you are changing the strategy based on user selection( as both are yielding the same result). You can change the access modifier if you want to expose the underlying service implementation to public

public interface ICaller{
    int DoStuff(dynamic parameters);
}
internal class ServiceForA : ICaller
{
    internal int DoStuff(dynamic parameters)
    {
       //implementation       
    }
}
internal class ServiceForB : ICaller
{
    internal int DoStuff(dynamic parameters)
    {
       //implementation
    }
}
public class ServiceProcessor 
{
    private ICaller _service;
    public ServiceProcessor(ICaller service)
    {
        _service = service;
    }
    public int Invoke(ICaller service)
    {
        return _service.DoStuff(dynamic parameters);
    }
}
static void Main()
{
    var processor = new ServiceProcessor(new ServiceForA());
    processor.Invoke();
    var processor = new ServiceProcessor(new ServiceForB());
    processor.Invoke();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.