예제 #1
0
        /// <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
        }