Beta: Util.Compile - Serialization Exception
Options
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:
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:
MyExtensions
System.Runtime.Serialization.SerializationException
Unable to find assembly 'MyExtensions.FW40, Version=0.0.0.0.
Culture=neutral, PublicKeyToken=null
Rule
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;}
}
Executor
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;
}
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 -
Cool :-)
-
I am still getting this exception on beta v4.53.16, please help
-
Are you certain? I can't reproduce this in that build.
-
100% certain
The image link doesn't work above...go to https://www.dropbox.com/s/num79dpw68ve7oo/LinqPadException.png?dl=0 -
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 beif (input.ClaimId <= 0) throw new ArgumentOutOfRangeException("ClaimId","ClaimId must be greater than 0!");
instead ofif (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.linqvoid 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 exceptionvoid 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