Search code examples
c#dynamicinterfaceexpandoobjectimpromptu-interface

'ExpandoObject' does not contain a definition for 'PropertyChanged'


I am attempting to use ImpromptuInterface to solve the issue I am having here. Adding Interface Implementation to ExpandoObject.

I am now able to access various properties of my interface in my base class but I can no longer subscribe to ExpandoObject's PropertyChanged event.

While troubleshooting I was able to simplify the issue as shown.

Service.cs

using ImpromptuInterface;

public Service()
{
    InitializeComponent();

    dynamic expando = new ExpandoObject();

    try
    {
        INotifyPropertyChanged obj = Impromptu.ActLike(expando);

        obj.PropertyChanged += obj_PropertyChanged;
    }
    catch (Exception ex)
    {
        EventLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
    }

    try
    {
        INotifyPropertyChanged obj = Impromptu.ActLike<INotifyPropertyChanged>(expando);

        obj.PropertyChanged += obj_PropertyChanged;
    }
    catch (Exception ex)
    {
        EventLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
    }
}

private void obj_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    throw new NotImplementedException();
}

I receive an error stating that

'System.Dynamic.ExpandoObject' does not contain a definition for 'PropertyChanged'

It occurs the each time I attempt to hook up the event handler in the constructor.

Event Log 1

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'System.Dynamic.ExpandoObject' does not contain a definition for 'PropertyChanged'
   at CallSite.Target(Closure , CallSite , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   at ActLike_INotifyPropertyChanged_dc51b6c65bf147d0b5f35218102e3c11.add_PropertyChanged(PropertyChangedEventHandler value)
   at Service..ctor()

Event Log 2

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'System.Dynamic.ExpandoObject' does not contain a definition for 'PropertyChanged'
   at CallSite.Target(Closure , CallSite , Object )
   at ActLike_INotifyPropertyChanged_dc51b6c65bf147d0b5f35218102e3c11.add_PropertyChanged(PropertyChangedEventHandler value)
   at Service..ctor()

Am I not allowed to use ImpromptuInterface this way?


Solution

  • The issue comes from the fact that ImpromptuInterface uses the DLR, and the DLR won't working with explicit interface calls, which is how it's implemented on Expando. It might be possible to be fixed generically by having the proxy check if it's target implements the exact interface impromptu is wrapping. I'd have to think about it more. Tracking with this issue.

    As a work around for this specific issue, Dynamitey.Dynamic.Dictionary:BaseDictionary works just like expando, and has PropertyChanged as a normal event property.