/// <summary> /// Builds the source of decision module and compile decision module into the assembly /// </summary> /// <param name="metadata">The metadata.</param> /// <param name="successorNodeLabelIdLookup">The successor node label id lookup.</param> /// <param name="predeccessorsOutputsNameTypeLookup">The predeccessors outputs name type lookup.</param> /// <param name="workspaceTypesDirectories">The workspace types directories.</param> /// <param name="loggerNameRoot">The logger name root.</param> private static void BuildSourceAndCompileDecisionModule(IDecision metadata, Dictionary <string, string> successorNodeLabelIdLookup, Dictionary <string, string> predeccessorsOutputsNameTypeLookup, List <string> workspaceTypesDirectories, LoggerNameRoot loggerNameRoot) { metadata.FireRequestLatestCode(); //create local componentlogger (ComponentLoggerImplementation implements MarshalByRefObject, thanks to which it can pass logs between appdomains TraceLabSDK.ComponentLogger logger = LoggerFactory.CreateLogger(loggerNameRoot, metadata.UniqueDecisionID, metadata); //construct the final code, and collect types assemblies locations to be referenced by the compilator HashSet <string> assembliesReferenceLocations; string finalDecisionModuleSourceCode = DecisionCodeBuilder.BuildCodeSource(metadata, workspaceTypesDirectories, successorNodeLabelIdLookup, predeccessorsOutputsNameTypeLookup, logger, out assembliesReferenceLocations); // Create the new domain with whatever current security evidence we're running with using the library helper LibraryHelper helper = new LibraryHelper(workspaceTypesDirectories); AppDomain newDomain = helper.CreateDomain("DecisionModuleCompilation"); newDomain.Load(Assembly.GetExecutingAssembly().GetName()); helper.PreloadWorkspaceTypes(newDomain); //// Load our output assembly into the other domain. DecisionModuleCompilator compiler = (DecisionModuleCompilator)newDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(DecisionModuleCompilator).FullName, false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.CreateInstance | BindingFlags.Instance, null, new object[] { }, System.Globalization.CultureInfo.CurrentCulture, new object[] { }); compiler.CompileDecisionModule(finalDecisionModuleSourceCode, metadata.SourceAssembly, assembliesReferenceLocations); #if !MONO_DEV //when developing on mono in MonoDevelop application crashes when unloading appdomain. //it only happens from within of MonoDevelop with attached debugger. Running normally, works fine. AppDomain.Unload(newDomain); #endif }
/// <summary> /// Builds the source of decision module and compile decision module into the assembly /// </summary> /// <param name="metadata">The metadata.</param> /// <param name="successorNodeLabelIdLookup">The successor node label id lookup.</param> /// <param name="predeccessorsOutputsNameTypeLookup">The predeccessors outputs name type lookup.</param> /// <param name="workspaceTypesDirectories">The workspace types directories.</param> /// <param name="loggerNameRoot">The logger name root.</param> private static void BuildSourceAndCompileDecisionModule(IDecision metadata, Dictionary<string, string> successorNodeLabelIdLookup, Dictionary<string, string> predeccessorsOutputsNameTypeLookup, List<string> workspaceTypesDirectories, LoggerNameRoot loggerNameRoot) { metadata.FireRequestLatestCode(); //create local componentlogger (ComponentLoggerImplementation implements MarshalByRefObject, thanks to which it can pass logs between appdomains TraceLabSDK.ComponentLogger logger = LoggerFactory.CreateLogger(loggerNameRoot, metadata.UniqueDecisionID, metadata); //construct the final code, and collect types assemblies locations to be referenced by the compilator HashSet<string> assembliesReferenceLocations; string finalDecisionModuleSourceCode = DecisionCodeBuilder.BuildCodeSource(metadata, workspaceTypesDirectories, successorNodeLabelIdLookup, predeccessorsOutputsNameTypeLookup, logger, out assembliesReferenceLocations); // Create the new domain with whatever current security evidence we're running with using the library helper LibraryHelper helper = new LibraryHelper(workspaceTypesDirectories); AppDomain newDomain = helper.CreateDomain("DecisionModuleCompilation"); newDomain.Load(Assembly.GetExecutingAssembly().GetName()); helper.PreloadWorkspaceTypes(newDomain); //// Load our output assembly into the other domain. DecisionModuleCompilator compiler = (DecisionModuleCompilator)newDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(DecisionModuleCompilator).FullName, false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.CreateInstance | BindingFlags.Instance, null, new object[] { }, System.Globalization.CultureInfo.CurrentCulture, new object[] { }); compiler.CompileDecisionModule(finalDecisionModuleSourceCode, metadata.SourceAssembly, assembliesReferenceLocations); #if !MONO_DEV //when developing on mono in MonoDevelop application crashes when unloading appdomain. //it only happens from within of MonoDevelop with attached debugger. Running normally, works fine. AppDomain.Unload(newDomain); #endif }