1

I am integrating a new payment way into our service project. I coded everything. Now I want it to be convenient to Solid principles. However, I am stuck how to overcome a case. Our service already have a method that called GetPaymentProfile and returns a class named PaymentProfile. After Integration I had to add a new PaymentProfile and method, because this new class has a new property.

Because of this, I obtained two class and two methods. Every step coded twice needlessly. I just want you to advise how I can do to overcome this.

preexisting method a class:

public class PaymentProfile
{
    public String Property1 = "";
    public String Property2 = "";
    public String Property3 = "";
    public String Property4 = "";
}

public PaymentProfile GetPaymentProfile(long aTicketType) {..}

class and method obtained after integration

public class PayCorePaymentProfile
{
    public String Property1 = "";
    public String Property2 = "";
    public String Property3 = "";
    public String Property4 = "";
    public String Property5 = "";
}

public PayCorePaymentProfile GetPayCorePaymentProfile(long aTicketType) {..}

What I thought

Creating a base class and then binding all sub-class with this base class, but I think it is not suitable for this case. Because I would return this base class without new property.

If I put everything in this base class, the old model has a new property needlessly.

*sorry for grammar rules and mistakes

ilyas varol
  • 788
  • 3
  • 10
  • 25
  • 1
    You should also consider how this will be used. Will the caller use all the properties, and therefore need to check what properties are available? Or is it just some opaque chunk of data that is only used somewhere else in the payment system? – JonasH Dec 01 '21 at 13:53
  • How is a `PaymentProfile` consumed? You need to decide on a common interface. – Johnathan Barclay Dec 01 '21 at 13:55

2 Answers2

2

You need to make PayCorePaymentProfile a child of PaymentProfile. In that case in the method GetPaymentProfile you will be able to return PayCorePaymentProfile.

public class PaymentProfile
{
    public string Property1 = "";
    public string Property2 = "";
    public string Property3 = "";
    public string Property4 = "";
}

public class PayCorePaymentProfile : PaymentProfile
{
    public string Property5 = "";
}

public PaymentProfile GetPaymentProfile(long aTicketType)
{
    if (usePayCore)
        return new PayCorePaymentProfile(); // You can return a child of PaymentProfile
    else
        return new PaymentProfile(); // Or just return a PaymentProfile
}

I hope, this will help.

Fmg
  • 105
  • 5
  • I really thank you for your effort but if I do this way, I cannot reach Property5 because there is no in PaymentProfile – ilyas varol Dec 01 '21 at 13:30
  • You can check what actual type was returned from GetPaymentProfile and cast it if neccessary. `var paymentProfile = GetPaymentProfile(someStuff);` `if (paymentProfile is PayCorePaymentProfile payCorePaymentProfile)` `Console.WriteLine($"GetPaymentProfile returned PayCorePaymentProfile, Property5 = {payCorePaymentProfile.Property5}");` – Fmg Dec 01 '21 at 14:03
1

There can be 1 Interface/BaseClass (with common properties) and 2 implementation of it with specific properties.

public abstract class Profile
{
    public string Property1 {get;set;}
    public string Property2 {get;set;}
    public string Property3 {get;set;}
    public string Property4 { get; set; }
}

public class PayCorePaymentProfile : Profile
{
    public string Property5 { get; set; } = "9";
}

public class PaymentProfile : Profile
{
    public string Property6 { get; set; } = "8";
}

Then based on the type, same Interface/BaseClass can be returned.

    public Profile GetPaymentProfile(string aTicketType)
    {
        if (aTicketType == "usePayCore")
            return new PayCorePaymentProfile(); 
        else
            return new PaymentProfile(); 
    }

Then typecast can be used to get actual implementation

    public void ShowProfile1()
    {
        var profile1 = (PayCorePaymentProfile) GetPaymentProfile("usePayCore");
    }

    public void ShowProfile2()
    {
        var profile2 = (PaymentProfile)GetPaymentProfile("other");
    }
Qwerty
  • 429
  • 2
  • 8