2

I have a third party library i am using. The have provided some of the classes for me to use to transfer data from one page to another, but i dont have the source code to make changes, for example

public class Customer
{
public string Name {get;set}
public Additional AdditionalDetails {get;set}
}

In this example i want to extend the Additional class and add properties to it without breaking the existing workings.

My controller and view works by passing in the customer class but all i want to do is add a new property to the Additional class.

I have tried to create a partial class but that didnt work and received the warning partial class with single part.

I then tried to create the class as

public class Additional

under the same namespace in my project and add the new property but that too didnt work (property didnt show).

Is there a way for me to extend this Additional class without breaking the existing code?

2
  • 1
    If the Additional class is not sealed, you can create a derived class that inherits from Additional and add the new properties you need. Commented Jul 5 at 7:31
  • Aparat from that, Instead of extending the Additional class, you can create a new class that contains an instance of Additional and adds the new properties you need. Extension method or wrapper both can handle that. Commented Jul 5 at 7:34

3 Answers 3

2

Is there a way for me to extend this Additional class without breaking the existing code?

In order extend the Additional class and add properties to it without breaking the existing workings, we could follow couple of approach, one of the way could be Wrapper Class

This approach allows you to keep using the existing third-party class (Customer and Additional) without any modifications to their usage while adding new properties to Additional.

First of all, I would be creating a customer with existing details, then need to Wrap the AdditionalDetails where would would inlcude the new proeprty and finally would build view model to pass the data to the view.

Let's have a look in practice:

Existing Class:

public class Additional
{
    public string ExistingProperty { get; set; }
}


public class Customer
{
    public string Name { get; set; }
    public Additional AdditionalDetails { get; set; }
}


public interface IAdditional
{
    string ExistingProperty { get; }
}

Wrapper Class:

public class ExtendedAdditional : IAdditional
{
    private readonly Additional _original;

    public ExtendedAdditional(Additional original)
    {
        _original = original ?? throw new ArgumentNullException(nameof(original));
    }

    public string ExistingProperty => _original.ExistingProperty;

    public string NewProperty { get; set; }
}

View Model:

public class CustomerViewModel
{
    public Customer Customer { get; set; }
    public ExtendedAdditional ExtendedAdditional { get; set; }
}

Controller:

public IActionResult Index()
 {
     
     var customer = new Customer
     {
         Name = "Kiron Test",
         AdditionalDetails = new Additional { ExistingProperty = "Existing Value" }
     };

    
     var extendedAdditional = new ExtendedAdditional(customer.AdditionalDetails)
     {
         NewProperty = "New Value"
     };

     
     var model = new CustomerViewModel
     {
         Customer = customer,
         ExtendedAdditional = extendedAdditional
     };

     return View(model);
 }

View:

@model CustomerViewModel

<h2>Customer Details</h2>
<p>Name: @Model.Customer.Name</p>

<h3>Additional Details</h3>
<p>Existing Property: @Model.ExtendedAdditional.ExistingProperty</p>
<p>New Property: @Model.ExtendedAdditional.NewProperty</p>

Output:

enter image description here

enter image description here

Note: In most cases, using a wrapper class (ExtendedAdditional) is considered more elegant and aligns better with principles of object-oriented design and separation of concerns. It provides a clear boundary between your application's logic and the third-party library's implementation.

2

You can create a new class that contains an instance of the Additional class and adds the extra properties you need. This way, you avoid modifying the existing class directly.

public class AdditionalExtended
{
    public Additional AdditionalDetails { get; set; }
    public string NewProperty { get; set; }
}

Then, update your Customer class to use the AdditionalExtended class:

public class Customer
{
    public string Name { get; set; }
    public AdditionalExtended AdditionalDetailsExtended { get; set; }
}

You will need to update your code to use the AdditionalDetailsExtended property instead of the AdditionalDetails property.

4
  • I was trying to avoid this as it would break the existing code Commented Jul 5 at 7:28
  • 1
    One way to do this is by using extension methods or a wrapper class to add additional functionality while keeping the existing structure intact.
    – Alec
    Commented Jul 5 at 7:32
  • Do you have an example? Please note the existing third party class cannot be changed in usage Commented Jul 5 at 7:36
  • Using extension methods public static class AdditionalExtensions { private static readonly Dictionary<Additional, string> additionalProperties = new Dictionary<Additional, string>(); public static void SetNewProperty(this Additional additional, string value) { additionalProperties[additional] = value; } public static string GetNewProperty(this Additional additional) { return additionalProperties.TryGetValue(additional, out var value) ? value : null; } }
    – Alec
    Commented Jul 5 at 7:47
2

At the time of writing this is still in preview, but in C# 13 you will have a new feature called "Extensions" which allows you to extend any class even from 3rd parties.

So you can do the following:

    public implicit extension AdditionalExtention for Additional
    {    
        //Extend property example 
        public string FullName { get => $"{this.Firstname} {this.Surname}"; }

        //Simple example of extension method getting an approximate age
        public int GetAge(this Additional additional)
        {
            return DateTime.Today.Year - this.DateOfBirth.Year;
        }
    }

Then you just use your class as normal.

    var age = customer.GetAge();
    var fullname = customer.Fullname;

Nick Chapsas explains the feature much better than I can in his video. https://www.youtube.com/watch?v=ueO5Cb3Emcw

Not the answer you're looking for? Browse other questions tagged or ask your own question.