Доступ к статическим данным из скомпилированной во время выполнения функции в Excel ДНК - PullRequest
0 голосов
/ 17 ноября 2018

Я почесал голову по этому вопросу.Я создаю архитектуру плагинов с помощью Excel ДНК и хочу компилировать новые функции во время выполнения и регистрировать их в Excel ДНК.Он прекрасно работает, пока я не попытаюсь получить доступ к статическим данным в контексте новых функций.Мои статические данные Toto равны нулю.

При добавлении некоторых журналов я обнаружил, что статический конструктор RuntimeCompiler вызывался дважды.Кажется, что новые функции работают в другом пространстве памяти.Тем не менее, когда я регистрирую Appdomain Id, внутри функции и снаружи, она кажется одинаковой.

Код работает отлично в модульном тесте.Вот почему я думаю, что это связано с управлением памятью ДНК в Excel / Excel.

Как я могу использовать то же пространство памяти с моими новыми загруженными функциями?

Кто-нибудь уже испытал этовопрос.?

Большое спасибо

альпага

namespace  test.xl.Loader
{

 public static class RuntimeCompiler
    {

        public static string Toto { get; set; }

        public static void CreateAndRegisterFunctions()
        {
            try
            {
                var wrapperClassPath =     CreateWrapperClassFromServiceDefinition();

                if (wrapperClassPath == null) return;

                var assemblyPath = CompileExecutable(wrapperClassPath);

                if (assemblyPath == null) return;

                var methodsToRegister =     GetMethodsFromAssembly(assemblyPath);

                if (methodsToRegister == null) return;

                ExcelAsyncUtil.QueueAsMacro(() =>     Integration.RegisterMethods(methodsToRegister));

            }
            catch (Exception e)
            {
                _logger.ErrorFormat(e.Message);
            }
        }

         private static string CreateWrapperClassFromServiceDefinition()
        {
            try
            {

                    Toto = "lol";

                    var generatedClass = @"

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using test.xl.Loader;

namespace  A
{
    public class Wrapper
    {
        public static object FlGetToto(string arg)
        {
            return test.xl.Loader.RuntimeCompiler.Toto;
        }
    }
}
                    ";

                    var tmp = Path.GetTempFileName()+".cs";

                    using (var file = new StreamWriter(tmp))
                    {
                        file.Write(generatedClass);
                    }

                    return tmp;

            }
            catch (Exception e)
            {
                _logger.Error($"Fail while creating Wrapper Class :     {e.Message}");
                return null;
            }
        }   

        private static List<MethodInfo> GetMethodsFromAssembly(string     assemblyPath)
        {
            try
            {
                var dllName = Path.GetFileName(assemblyPath);

                var assemblyFullName = AssemblyName.GetAssemblyName($".\\    {dllName}");

                var assembly = Assembly.Load(assemblyFullName);

                AppDomain.CurrentDomain.Load(assembly.GetName());

                Type myType = assembly.GetType("A.Wrapper");

                return myType.GetMethods().ToList().Where(x => x.Module.Name     == dllName).ToList();
            }
            catch (Exception e)
            {
                _logger.Error($"Fail while getting methods from Assembly :     {e.Message}");
                return null;
            }
        }
    }
}
...