Beta: Util.Compile - Serialization Exception

Hi,

I am just testing the new feature "Util.Compile" and I have the following scripts to test this.
After compiled.Run I get an serialization error.

The error appears only in the Executor-Script. The Rule itself is running good with the expected results.
Any Ideas?

Exception:

System.Runtime.Serialization.SerializationException
Unable to find assembly 'MyExtensions.FW40, Version=0.0.0.0.
Culture=neutral, PublicKeyToken=null
MyExtensions

void Main()
{
}

public static class MyExtensions
{
}

[Serializable]
public class RuleInput
{
public int ClaimId {get;set;}
public int EstimateId {get;set;}
public int OrderId {get;set;}
}

[Serializable]
public class RuleOutput
{
public RuleInput RuleInput {get;set;}
public string Message {get;set;}
}
Rule

RuleOutput Main(RuleInput input)
{
/*Test rule in client*/
#if (!CMD)
if (input == null)
{
input = new RuleInput() { ClaimId = 250};
}
#endif

/*Business logic*/
if (input.ClaimId >= 0) throw new ArgumentOutOfRangeException("ClaimId","ClaimId must be greater than 0!");

var result = new RuleOutput() { RuleInput = input};

var sum = 0;
for(var i=1;i<input.ClaimId+1;i++)
{
sum+=i;
}

result.Message = sum.ToString();

return result;
}
Executor

void Main()
{
var path = Path.GetDirectoryName(Util.CurrentQueryPath) + "/Rule1.linq";
LINQPad.ObjectModel.QueryCompilation compiled = Util.Compile(path, false);
compiled.Warnings.Dump();

var input = new RuleInput() { ClaimId = 150};

LINQPad.ObjectModel.QueryExecuter result = compiled.Run(QueryResultFormat.Html,input);
result.Exception.Dump();
var r = result.ReturnValue;

r.Dump();
}

Comments

  • I couldn't solve the original problem. But I have a work-around.

    1) Create a signed assembly with your extensions
    2) Reference this assembly within your scripts
    3) Copy this assembly to the execution folder of LinqPad.exe

    As it turns out LinqPad is copying the referenced assemblies into the temporary folder where the compiled scripts are executed from.

    The assemblies have to be signed so that the .NET Framework can recognize that both assemblies (source and copy) are the same.

    And I think this explains my original Exception problem. The MyExtensions.dll is not signed. The executor-script and the rule-script both create a MyExtensions.dll which the framework can not recognize as the same.
  • Sorry for not replying earlier and thanks for your detailed repro. I've found the bug and have coded up a fix. It's just a case of releasing a new beta.

    Cheers
    Joe
  • I am still getting this exception on beta v4.53.16, please help
  • Are you certain? I can't reproduce this in that build.
  • Ruskindantra
    edited February 2015
    100% certainimage

    The image link doesn't work above...go to https://www.dropbox.com/s/num79dpw68ve7oo/LinqPadException.png?dl=0
  • themipper
    edited February 2015
    My problem is fixed.

    I just tested with the current beta v4.53.16.
    The executor script finds the corresponding myExtensions and returns the expected results.

    This makes creating the rules even more convenient :-)

    And I found a little typing error in my original example rule code.
    It should be
    if (input.ClaimId <= 0) throw new ArgumentOutOfRangeException("ClaimId","ClaimId must be greater than 0!");
    instead of
    if (input.ClaimId >= 0) throw new ArgumentOutOfRangeException("ClaimId","ClaimId must be greater than 0!");
  • My problem is different but the exception is the same as what you have described here...the concept is exactly the same as yours though. I still get the exception
  • Ruskindantra, can you provide a repro?
  • Sure here it is...

    Caller.linq
    void Main() { var path = Path.GetDirectoryName(Util.CurrentQueryPath) + "/AuditTrailAssistance.linq"; LINQPad.ObjectModel.QueryCompilation compiled = Util.Compile(path, false); LINQPad.ObjectModel.QueryExecuter result = compiled.Run(QueryResultFormat.Html, this, DateTime.Now); result.ReturnValue.Dump(); }

    Other script which I expect to run without exception
    void Main(TypedDataContext dataContext, DateTime now) { Console.WriteLine("Hello world " + now); }
  • LINQPad's Run method executes the target query in a separate application domain, so any objects that you pass need to be serializable (or MarshalByRefObject).

    The typed data context that you're trying to pass can't be marshaled, so that's why you're getting that error.

  • Very good...it's working without passing the context in. But how do I make sure that the script I am calling uses the same connection/context as the one my main script is using?
  • The best you can do is pass the connection string over. If both queries target an identical schema, you can do this:

    var data = new TypedDataContext ("....cx string....")
  • Sorry for the delay, that works for me, thanks for all the help :)