none
Extension Methods in Runtime Compiled DLL RRS feed

  • Question

  • I compile add-ons to my application at runtime using CodeDomProvider.

    Everything works as expected, except Extension Methods, defined in my application.

    If I reference the application in another project, the extension methods can be called.

    I have Extension methods like this:

    <Extension()>
    Public Function InQuotes(Text As String, Optional Quote As String = "'") As String
    Return Quote & Text & Quote
    End Function

    I can call this method from my runtime code, but not as an extension method

    Dim Quoted = InQuotes("Test") 'This Works

    Dim Quoted = "Test".InQuotes() 'Gives error: "InQuotes is not a member of String"

    I have tried adding:

    Imports System.Runtime.CompilerServices

    This is only in .Net 3.5.

    if I compile with 4.5 it works, so I assume all I'm missing is a reference or import that is automatically included with 4.5

    Anyone have any suggestions?

    Thank you


    Tuesday, August 7, 2018 8:54 PM

All replies

  • Only thing I can think of is your module is not public e.g.

    Module Extensions
        <Extension()>
        Public Function InQuotes(Text As String, Optional Quote As String = "'") As String
            Return Quote & Text & Quote
        End Function
    End Module

    It needs to be

    Public Module Extensions
        <Extension()>
        Public Function InQuotes(Text As String, Optional Quote As String = "'") As String
            Return Quote & Text & Quote
        End Function
    End Module


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Tuesday, August 7, 2018 10:22 PM
    Moderator
  • If possible, show a short fragment that generates the assembly using CodeDomProvider.


    Wednesday, August 8, 2018 4:58 AM
  • It is public, and I can use the methods, but not as extensions.

    Here's the basic compile code with a sample of the source below

    CompilerParameters = New Compiler.CompilerParameters With CompilerParameters   .WarningLevel = 4   .GenerateInMemory = InMemory   .TreatWarningsAsErrors = False .ReferencedAssemblies.Add("System.dll")   .ReferencedAssemblies.Add("System.Drawing.dll")   .ReferencedAssemblies.Add("System.Windows.Forms.dll")   .ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")   .ReferencedAssemblies.Add(AppDir & "Microsoft.mshtml.dll")   .ReferencedAssemblies.Add(AppDir & "Extensions.dll")   .ReferencedAssemblies.Add(AppDir & "HelpViewer.dll")   .ReferencedAssemblies.Add(AppDir & "MdiTabControl.dll")   .ReferencedAssemblies.Add(AppDir & "ChilkatDotNet2.dll")   .ReferencedAssemblies.Add(AppDir & "PDFLibNet.dll")   .ReferencedAssemblies.Add(AppDir & "Packing Partner V3.exe")

    .OutputAssembly = File End With Using CD = Compiler.CodeDomProvider.CreateProvider("VisualBasic")   Dim CR As Compiler.CompilerResults   CR = CD.CompileAssemblyFromSource(CompileParameters, SourceCode)   If Not CR.Errors.HasErrors Then     RefAssembly = CR.CompiledAssembly   End If


    Imports System
    Imports System.Drawing
    Imports System.IO
    Imports System.Collections.Generic
    Imports System.ComponentModel
    Imports System.Text
    Imports System.Windows.Forms
    Imports AiMCo.Extensions
    Imports AiMCo.Extensions.ExtMsgBox
    Imports AiMCo.PackingPartnerV3
    Imports Microsoft.VisualBasic
    Imports mshtml
    Imports PDFLibNet
    
    Module ScriptModule
    
    Function Test()
      'InQuotes is a function in the application, following works:
      Dim x = InQuotes("Test")
      'Following causes "InQuotes is not a member of String
      Dim x = "Test".InQuotes()
    End Function


    Wednesday, August 8, 2018 8:35 AM
  • So let's say the extension method is in a public code module and in class project. In another project that references the class project with the language extension you are saying this is the case that 

    InQuotes is not a member of String

    So we end up with the following as a test.

    Public Class Form1
        Public Sub Demo()
            Dim firstName As String = "Karen"
            Dim results = firstName.InQuotes
        End Sub
    End Class

    .

    Public Class Form1
        Public Sub Demo()
            MessageBox.Show("Karen".InQuotes)
        End Sub
    End Class

    I'd expect it to work (which it does).

    So if your InQuotes works as a function, if you right click on 

    Dim x = InQuotes("Test")

    And select "Peek definition" or "Go to definition" it takes you to the proper method?


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Wednesday, August 8, 2018 2:02 PM
    Moderator
  • Yes, that is all correct from Visual Studio, but not when compiling my own code.

    The code isn't developed in Visual Studio, it's for users to create their own add-ons.

    You can see it in the demo app here: www.aimcosoftware.co.uk/download/ppv34release.exe

    On the main menu, goto Tools>Scripting and enter (InQuotes was just an example, TrimAll is a real method) and run:

    Sub Script_Start()
      Dim NameWithSpace As String = "  Karen  "
      Dim Res1 As String = TrimAll(NameWithSpace)
      Dim Res2 As String = NameWithSpace.TrimAll
    End Sub

    TrimAll is in a public module and defined as:

    <Extension()>
    Public Function TrimAll(Text As String) As String
      Return Text.Trim(EndAll)
    End Function

    It works as a standard method, but isn't recognised by the compiler as an extension.

    I have read that a reference to system.linq is required but that hasn't worked either.

    Thanks for your help



    Wednesday, August 8, 2018 2:23 PM
  • Sorry but I don't have anything else to offer.

    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Wednesday, August 8, 2018 3:13 PM
    Moderator
  • OK, thanks for your input.
    Wednesday, August 8, 2018 3:30 PM
  • Have you tried to reproduce the problem using a new simplest project, which builds the assembly that only includes InQuotes, but does not contain any reference to third-party libraries? If the same issue is observed, you can give the archived project (sources) here.



    • Edited by Viorel_MVP Wednesday, August 8, 2018 3:41 PM
    Wednesday, August 8, 2018 3:36 PM
  • I haven't because it's not desperate. We can still use the methods, just not as extensions.

    I had hoped that someone would say, "yes, I had that problem and fixed it with..."

    Wednesday, August 8, 2018 3:53 PM
  • Some more information on this issue, as I just bumped into it.

    Summary: Extentions in properly defined extention modules are not recognized when using CodeDomProvider or VBCodeProvider to compile code at run time.  They pass the compile check, but fail at execution with MissingMemberException.

    To be absolutely clear, I won't use any custom extensions.  The common System.Linq extensions do not work within CodeDomProvider and VBCodeProvider compiled code.  ToList, Select, Any, etc.

    Tuesday, November 27, 2018 7:02 PM
  • Just to be clear.  As Karen said the Extensions library must have code like this

        Public Module Extensions
            <Extension()>
            Public Function InQuotes(Text As String, Optional Quote As String = "'") As String
                Return Quote & Text & Quote
            End Function
        End Module
    

    Extensions must be in modules. I get the feeling that you don't have the extension in a module.

    Just my $0.02


    "Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it."

    - from former MSDN User JohnWein

    SerialPort Info

    Multics - An OS ahead of its time.

    Tuesday, November 27, 2018 7:15 PM