Adding new object property dynamically from extension method

1.4k views Asked by At

Here is my scenario... I want to have some base class and have some set of extension methods to this class that will be hosted probably in different assemblies. Depending on what assemblies added to the project, different properties should be calculated and stored inside.

I have some base class

public class AObject
{
    public string PropertyA { get; set; }
    public int PropertyB { get; set; }
}

and do have some extension method to this class

public static class AObjectExtensions
{
    public static void DoSomething(this AObject a, string value)
    {
        a.PropertyC = value;
    }
}

What I want to get, I want to do some calculations inside extension method DoSomething and save results as PropertyC inside AObject. AObject doesn't have PropertyC by default, so I want to add it dynamically. I figured out that to work with dynamic properties I have to use ExpandoObject, but not sure that I see how it can be used here...

So, the main question is it a good scenario at all or I have to think about something else?

1

There are 1 answers

2
Sebastian Schumann On BEST ANSWER

You need to inherit your object from DynamicObject:

public class AObject : DynamicObject
{
    public string PropertyA { get; set; }

    public int PropertyB { get; set; }

    #region Dynamic Part

    private readonly Dictionary<string, object> _members = new Dictionary<string, object>();

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        this._members[binder.Name] = value;
        return true;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        return this._members.TryGetValue(binder.Name, out result) || base.TryGetMember(binder, out result);
    }

    public override IEnumerable<string> GetDynamicMemberNames()
    {
        return this._members.Keys;
    }

    #endregion
}

Your extension method has to be changed to:

public static class AObjectExtensions
{
    public static void DoSomething(this AObject a, string value)
    {
        ((dynamic)a).PropertyC = value;
    }
}

You have the ability to iterate over all dynamic members using GetDynamicMemberNames() and if AObject provides an indexer or a getter method that accesses this._members you can access to all dynamic values.

EDIT: There meight be a problem using this solution. I didn't tested it. ((dynamic)a).PropertyA meight be hidden by Try(Get|Set)Member. If so you can change the getter and setter of PropertyA and ProprertyB to access the _members or you can handle this cases in Try(Get|Set)Member. Adding these properties to _member opens up the possibility to iterate over these members too.