zzzprojects / Eval-Expression.NET

C# Eval Expression | Evaluate, Compile, and Execute C# code and expression at runtime.
https://eval-expression.net/
Other
449 stars 86 forks source link

Issues with dynamically generated types #28

Closed rodro75 closed 6 years ago

rodro75 commented 6 years ago

Hi @JonathanMagnan ,

I'm back, sorry! :-D

This time I'm having some problems with referencing instance members of a string property, which is declared in a dynamically generated type.

Given a datacontext that has a property named Custom of type dynamic, which is assigned an instance of a dynamically generated class that has a Cluster property of type string, the following expression throws an exception:

bool result = Eval.Execute("Custom.Cluster.Contains(\"Foo\")", datacontext);

Attached is a solution with a minimal repro of what I'm doing, stripped down from my real project.

ExpressionsEvalTests.zip

Best Regards,

-Rodrigo-

JonathanMagnan commented 6 years ago

Hello @rodro75 ,

Thank you for reporting.

We will try to check if we can find a fix to include it in the today release.

Best Regards,

Jonathan

JonathanMagnan commented 6 years ago

Hello @rodro75 ,

While it could be possible to fix it for the Eval.Execute since the value is known at this time, it will be impossible for us to support it for Eval.Compile as value is unknown.

When using with Eval.Compile, the Cluster is still an object so it doesn't have any Contains method. To make it work with it, you will need to cast the property to string as you would normally do without our library:

bool result = campaignContext.EvaluateExpression("((string)Custom.Cluster).Contains(\"HCM\")", dataContext);

We will continue to investigate for the Eval.Execute to see if we can or not support it.

Best Regards,

Jonathan

rodro75 commented 6 years ago

Hmmm... I see.

But the point of generating an actual Type was really to help the compiler know that Cluster is a string member. Or are you talking about the fact that DataContext.Custom property is of type dynamic so you don't even know about the generated type?

Besides, my CampaignContext.Validate method, which uses Eval.Compile under the hood, doesnt complain at all when given the problematic code (which is actually a bad thing for us because the user won't know about the issue until runtime).

What if I generated the whole DataContext so that the Custom property's type is made explicit?

Thanks man!

-Rodrigo-

JonathanMagnan commented 6 years ago

Or are you talking about the fact that DataContext.Custom property is of type dynamic so you don't even know about the generated type?

Exactly, when we compile, we only know about type and not value (unless we use some workaround). So a dynamic type is simply an object at this stage.

What if I generated the whole DataContext so that the Custom property's type is made explicit? Not sure to exactly understand but if all types are explicit, you should not get any issue I believe.

I recommend you to try and let us know

Best Regards,

Jonathan

JonathanMagnan commented 6 years ago

Hello @Jon,

This issue will be closed since it has been answered.

Feel free to reopen it if you feel otherwise.

Best Regards,

Jonathan

rodro75 commented 6 years ago

Hi @JonathanMagnan ,

Sorry for the delay. I made further tests by generating the whole DataContext type and now it works. Basically instead of having:

class DataContext {
    SystemDataContext System;
    dynamic Custom; //<-- will be assigned an instance of MyGeneratedCustomClass
}

now I have:

class MyGeneratedDataContextClass {
    SystemDataContext System;
    MyGeneratedCustomClass Custom;
}

so that when Eval.Execute inspects the Custom field it understands its type by looking at the corresponding FieldInfo.

I guess it would be possible for Eval.Execute to get the type from the actual runtime value as well, which I think would be a more dynamic/javascript-ish behavior. I'm not sure whether that would be a breaking change though.

Of course Eval.Compile is a different story, I understand that.

Best Regards,

-Rodrigo-