Hi Kevin,
I think you should use BaseAssemblyManager instead of default AssemblyManager. AssemblyManager scans all assemblies loaded into application domain, if it can't locate dependent assemblies you will have "ReflectionTypeLoadException".
With BaseAssemblyManger you might also see performance increase, which should be important for Web applications.
You can take a look at the following references to see how BaseAssemblyManager is used:
Regards,
Petro
On Wednesday, June 27, 2012 4:58:05 PM UTC+2, Kevin wrote:
I am using Script.Net within the context of a web application, and it normally works fine. However, when we moved our web application to .Net 4, we would get the following error...
System.TypeInitializationException: The type initializer for 'Nested'
threw an exception. --->
System.Reflection.ReflectionTypeLoadException: Unable to load one or
more of the requested types. Retrieve the LoaderExceptions property for
more information.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module) at
System.Reflection.RuntimeModule.GetTypes() at
System.Reflection.Assembly.GetTypes() at
Orbifold.SSharp.Runtime.BaseAssemblyManager.AddAssembly(Assembly
assembly) at
Orbifold.SSharp.Runtime.BaseAssemblyManager.ScanAssemblies()
at
Orbifold.SSharp.Runtime.BaseAssemblyManager.Initialize(ScriptConfiguration
configuration) at
Orbifold.SSharp.Runtime.AssemblyManager.Initialize(ScriptConfiguration
configuration) at Orbifold.SSharp.Runtime.RuntimeHost.Initialize(Stream
configuration) at
Orbifold.SSharp.Runtime.RuntimeHost.Initialize() at
Infosnap.Secure.GlobalServices.ScriptEvaluationService..ctor() at
Infosnap.Secure.GlobalServices.ScriptEvaluationService.Nested..cctor()
--- End of inner exception stack trace --- at
Infosnap.Secure.GlobalServices.ScriptEvaluationService.get_Instance()
at Infosnap.Secure.Domain.ScriptFunction.Execute(List`1 arguments) at
Infosnap.Secure.Domain.Forms.SmartFormUpdate.Evaluate(NameValueCollection
formData, IDictionary`2 sessionData, ScriptFunction function) at
Infosnap.Secure.AdminPortal.Controllers.PreviewController.Forms()
I have highlighted the important parts.
When I dug into the LoaderExceptions, I found that it was having a problem loading System.Web.Mvc. So, in doing some research, I found that if I added the following to my web.config file, it seemed to solve the issue.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
BUT, now, whenever we deploy updates to the web application, we start immediately getting these errors again. It takes an app pool recycle to solve the issue.
I have set up Script.Net into a singleton like this...
public sealed class ScriptEvaluationService
{
#region Thread-safe, lazy Singleton
/// <summary>
/// This is a thread-safe, lazy singleton. See http://www.yoda.arachsys.com/csharp/singleton.html
/// for more details about its implementation.
/// </summary>
public static ScriptEvaluationService Instance
{
get
{
return Nested.ScriptEvaluationService;
}
}
/// <summary>
/// Initializes the NHibernate session factory upon instantiation.
/// </summary>
private ScriptEvaluationService()
{
InitializeRuntimeHost();
}
/// <summary>
/// Assists with ensuring thread-safe, lazy singleton
/// </summary>
private class Nested
{
static Nested() { }
internal static readonly ScriptEvaluationService ScriptEvaluationService =
new ScriptEvaluationService();
}
#endregion
private void InitializeRuntimeHost()
{
// Initialize the runtime host.
RuntimeHost.Initialize();
}
public bool Evaluate(string expression)
{
Script script = Script.Compile(expression);
bool result = (bool)script.Execute();
return result;
}
public bool Evaluate(string expression, Dictionary<string, string> contextItems)
{
Script script = Script.Compile(expression);
foreach (KeyValuePair<string, string> pair in contextItems)
script.Context.SetItem(pair.Key, pair.Value);
bool result = (bool)script.Execute();
return result;
}
public bool Evaluate(string expression, Dictionary<string, object> contextItems)
{
Script script = Script.Compile(expression);
foreach (KeyValuePair<string, object> pair in contextItems)
script.Context.SetItem(pair.Key, pair.Value);
bool result = (bool)script.Execute();
return result;
}
public object Execute(string code)
{
Script script = Script.Compile(code);
return script.Execute();
}
public object Execute(string code, Dictionary<string, object> contextItems)
{
Script script = Script.Compile(code);
foreach (KeyValuePair<string, object> pair in contextItems)
script.Context.SetItem(pair.Key, pair.Value);
object result = script.Execute();
return result;
}
}
I am not sure how Script.Net loads the .Net assemblies, or why it might try to load System.Web.Mvc. I appreciate any thoughts or ideas on this!
Thanks,
Kevin