Ejemplo n.º 1
0
        private async Task <InitResult> DoInit(InitParameter parameter, string code)
        {
            var    config = new Mediator.Config(parameter.ModuleConfig);
            string libs   = config.GetOptionalString("csharp-libraries", "");
            bool   cache  = config.GetOptionalBool("csharp-cache-scripts", true);

            string[] assemblies = libs
                                  .Split(new char[] { ';', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)
                                  .Select(s => s.Trim())
                                  .ToArray();

            string[] absoluteAssemblies = assemblies.Select(d => Path.GetFullPath(d)).ToArray();
            foreach (string assembly in absoluteAssemblies)
            {
                if (!File.Exists(assembly))
                {
                    throw new Exception($"csharp-library does not exist: {assembly}");
                }
            }

            absoluteAssemblies = absoluteAssemblies.Select(assembly => {
                if (assembly.ToLowerInvariant().EndsWith(".cs"))
                {
                    CompileResult compileRes = CompileLib.CSharpFile2Assembly(assembly);
                    Print(compileRes, assembly);
                    return(compileRes.AssemblyFileName);
                }
                return(assembly);
            }).ToArray();

            var referencedAssemblies = new List <Assembly>();

            foreach (string assembly in absoluteAssemblies)
            {
                try {
                    Assembly ass = Assembly.LoadFrom(assembly);
                    referencedAssemblies.Add(ass);
                }
                catch (Exception exp) {
                    throw new Exception($"Failed to load csharp-library {assembly}: {exp.Message}");
                }
            }

            CodeToObjectBase objMaker;

            if (cache)
            {
                objMaker = new CodeToObjectCompile();
            }
            else
            {
                objMaker = new CodeToObjectScripting();
            }

            object obj = await objMaker.MakeObjectFromCode(parameter.Calculation.Name, code, referencedAssemblies);

            inputs  = GetIdentifiableMembers <InputBase>(obj, "", recursive: false).ToArray();
            outputs = GetIdentifiableMembers <OutputBase>(obj, "", recursive: false).ToArray();
            states  = GetIdentifiableMembers <AbstractState>(obj, "", recursive: true).ToArray();

            var eventProviders = GetMembers <EventProvider>(obj, recursive: true);

            foreach (EventProvider provider in eventProviders)
            {
                provider.EventSinkRef = this;
            }

            Type type = obj.GetType();

            MethodInfo[] methods =
                type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
                .Where(m => m.Name == "Step" && IsStepSignature(m))
                .ToArray();

            if (methods.Length == 0)
            {
                throw new Exception("No Step(Timestamp t, TimeSpan dt) method found.");
            }
            MethodInfo step = methods[0];

            stepAction = (Action <Timestamp, Duration>)step.CreateDelegate(typeof(Action <Timestamp, Duration>), obj);

            foreach (StateValue v in parameter.LastState)
            {
                AbstractState state = states.FirstOrDefault(s => s.ID == v.StateID);
                if (state != null)
                {
                    state.SetValueFromDataValue(v.Value);
                }
            }

            return(new InitResult()
            {
                Inputs = inputs.Select(MakeInputDef).ToArray(),
                Outputs = outputs.Select(MakeOutputDef).ToArray(),
                States = states.Select(MakeStateDef).ToArray(),
                ExternalStatePersistence = true
            });
        }