Взаимодействие открытых переменных между сборками, созданными InMemory из CodeDom

Пользователи могут запускать несколько экземпляров сборок InMemory из основного приложения. Проблема в том, что общедоступные переменные в сборках InMemory перезаписывают друг друга. Есть ли способ исправить это?

Я также попытался переименовать оценщик пространства имен и оценщик класса по-разному для каждого экземпляра, но это не помогло.

Namespace Evaluator

    Public Module GlobalSettings
        Public Var1 As String
        Public Var2 As String
        Public TextBox1 As New TextBox
        Public TextBox2 As New TextBox
    End Module

    Public Class Evaluator

        '...insert code here

    End Class

End Namespace

Friend Function CompileCode() As Object
    Dim compResults As CompilerResults
    Dim code = GetCode()

    Dim provOptions As New Dictionary(Of String, String)
    provOptions.Add("CompilerVersion", "v3.5")

    Dim vbProv = New VBCodeProvider(provOptions)

    Dim vbParams = New CompilerParameters()
    vbParams.ReferencedAssemblies.Add("mscorlib.dll")
    vbParams.ReferencedAssemblies.Add("System.dll")
    vbParams.ReferencedAssemblies.Add("System.Windows.Forms.dll")
    vbParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")
    vbParams.ReferencedAssemblies.Add("System.Data.dll")

    vbParams.TreatWarningsAsErrors = False
    vbParams.GenerateExecutable = False
    vbParams.GenerateInMemory = True

    compResults = vbProv.CompileAssemblyFromSource(vbParams, code)

     _evaluator = compResults.CompiledAssembly.CreateInstance("Evaluator.Evaluator")

End Function

person Troy Mitchel    schedule 23.07.2013    source источник


Ответы (1)


После долгих проб и тестов я нашел решение. Это не имело ничего общего с общедоступными переменными, а также изменение имени пространства имен и класса для каждого экземпляра также не работало, каждая сборка кода по-прежнему обменивалась информацией туда и обратно. Итак, ответ... Поскольку несколько экземпляров вызывались из одного и того же родительского приложения, объект _evaluator должен быть независимым для каждого экземпляра в коде компилятора и вызывающем коде.

В итоге я разрешил 5 экземпляров, которые можно было запускать одновременно из приложения Windows. Если один экземпляр закрыт, программа назначает следующему вызываемому экземпляру доступный идентификатор, который я сохраняю в парных значениях общедоступного списка (Of...). этот код не показан здесь, как назначать и удалять.

Dim _evaluator1 As Object
Dim _evaluator2 As Object
Dim _evaluator3 As Object
Dim _evaluator4 As Object
Dim _evaluator5 As Object

Friend Function CompileCode() As Object
   Dim compResults As CompilerResults
   Dim code = GetCode()

   Dim provOptions As New Dictionary(Of String, String)
   provOptions.Add("CompilerVersion", "v3.5")

   Dim vbProv = New VBCodeProvider(provOptions)

   Dim vbParams = New CompilerParameters()
   vbParams.ReferencedAssemblies.Add("mscorlib.dll")
   vbParams.ReferencedAssemblies.Add("System.dll")
   vbParams.ReferencedAssemblies.Add("System.Windows.Forms.dll")
   vbParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")
   vbParams.ReferencedAssemblies.Add("System.Data.dll")

   vbParams.TreatWarningsAsErrors = False
   vbParams.GenerateExecutable = False
   vbParams.GenerateInMemory = True

   compResults = vbProv.CompileAssemblyFromSource(vbParams, code)

     Select Case CurrentInstance
         Case 1 : _evaluator1 = compResults.CompiledAssembly.CreateInstance("Evaluator.Evaluator")
         Case 2 : _evaluator2 = compResults.CompiledAssembly.CreateInstance("Evaluator.Evaluator")
         Case 3 : _evaluator3 = compResults.CompiledAssembly.CreateInstance("Evaluator.Evaluator")
         Case 4 : _evaluator4 = compResults.CompiledAssembly.CreateInstance("Evaluator.Evaluator")
         Case 5 : _evaluator5 = compResults.CompiledAssembly.CreateInstance("Evaluator.Evaluator")
     End Select

End Function

Вызов

  Dim objResult As Object

        Select Case CurrentInstance
            Case 1 : objResult = _evaluator1.GetType.InvokeMember(name, BindingFlags.DeclaredOnly Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.InvokeMethod, Nothing, _evaluator1, args)
            Case 2 : objResult = _evaluator2.GetType.InvokeMember(name, BindingFlags.DeclaredOnly Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.InvokeMethod, Nothing, _evaluator2, args)
            Case 3 : objResult = _evaluator3.GetType.InvokeMember(name, BindingFlags.DeclaredOnly Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.InvokeMethod, Nothing, _evaluator3, args)
            Case 4 : objResult = _evaluator4.GetType.InvokeMember(name, BindingFlags.DeclaredOnly Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.InvokeMethod, Nothing, _evaluator4, args)
            Case 5 : objResult = _evaluator5.GetType.InvokeMember(name, BindingFlags.DeclaredOnly Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.InvokeMethod, Nothing, _evaluator5, args)
        End Select
person Troy Mitchel    schedule 25.07.2013