1

I have created a Nuget.org package, with the following (abridged) code:

namespace MyNugetPackageNS
    module MyNugetModule = 
        open ExcelDna.Integration

        // this function is NOT seen in the package user's Excel session
        [<ExcelFunction(Category="Test", Description="Add 1.")>]
        let plusOne ([<ExcelArgument(Description= "Value.")>] value: double) : obj = 
            value + 1.0 |> box

I was hoping that if a user installs the package and adds it into his own library, all the Excel functions defined in the package (e.g. plusOne) would automatically be visible within Excel, but it isn't the case. It seems that the user has to "wrap" the package Excel functions in order to make them visible in Excel, e.g. :

namespace UserNS
    module UserModule = 
        // need to install the nuget package from Nuget.org
        open MyNugetPackageNS.MyNugetModule
        open ExcelDna.Integration

        // this function is seen in the package user's Excel session
        [<ExcelFunction(Category="Test", Description="Add 1.")>]
        let plusOne2 ([<ExcelArgument(Description= "Value.")>] value: double) : obj = 
            MyNugetModule.plusOne value

My question : Is there a way to make the package's Excel functions automatically "visible" in the package user's Excel session, without wrapping each function before hand?

=================

EDIT:

Following Augusto's tip, I added Excel-DNA Registration package to my Nuget project, and based on the examples found here, I added the MakeAddInsVisible snippet which explicitly loads the Nuget project's Excel functions.

namespace MyNugetPackageNS
open ExcelDna.Integration
open ExcelDna.Registration

type MakeAddInsVisible () =
    interface IExcelAddIn with
        member this.AutoOpen ()  = 
            ExcelRegistration.GetExcelFunctions ()
            |> ExcelRegistration.RegisterFunctions
        member this.AutoClose () = ()

    module MyNugetModule = 
        open ExcelDna.Integration

        // this function is STILL NOT seen in the package user's Excel session
        [<ExcelFunction(Category="Test", Description="Add 1.")>]
        let plusOne ([<ExcelArgument(Description= "Value.")>] value: double) : obj = 
            value + 1.0 |> box

I also added the ExplicitRegistration flag to my Nuget project's .dna file :

<DnaLibrary Name="MyNugetPackageNS Add-In" RuntimeVersion="v4.0" xmlns="http://schemas.excel-dna.net/addin/2018/05/dnalibrary">
  <ExternalLibrary Path="MyNugetPackageNS.dll" ExplicitExports="true" ExplicitRegistration="true" LoadFromBytes="true" Pack="true" IncludePdb="false" />
</DnaLibrary>

"Locally" (meaning when I use MyNugetPackageNS as a normal package, before exporting it to Nuget.org), this seems to work as expected: Because of the ExplicitRegistration="true" flag in the .dna file, the Excel functions are still registered because of the presence of the MakeAddInsVisible snippet (and no Excel function would be registered when the snippet is commented out).

Now I exported this new code to nuget.org and downloaded the package into the nuget package user's project (without any modifications to the above namespace UserNS ... code).

Unfortunately MyNugetPackageNS Excel functions are still invisible from the nuget package user's Excel session.

What did I miss?

Janthelme
  • 989
  • 10
  • 23

3 Answers3

1

In order to register new functions at run-time you'll have to use the Registration extension. Here is an example of how to use it:

https://stackoverflow.com/a/60079589

C. Augusto Proiete
  • 24,684
  • 2
  • 63
  • 91
  • Thanks Augusto. I have described what I tried as an edit to the original question above. Unfortunately I could not make it work. What did I miss? – Janthelme Jun 20 '20 at 08:04
  • The implementation of `ExcelRegistration.GetExcelFunctions()` only looks in assemblies that are listed as `` in the .dna file. Not all assemblies that are referenced by the project. So one would need some extra code to enumerate functions from additional assemblies, or add an `` entry in the .dna file. – Govert Jun 20 '20 at 14:37
1

The extra library that you add to your user's project will not be recognized by the Excel-DNA startup without some indication that this library should be scanned for Excel functions.

One way that your user can indicate that your library should be checked (and the functions registered) is for them to add an <ExternalLibrary> entry into their add-in .dna file.

Another approach is what Augusto describes, where your user can add some code to their add-in to register the function. But the code will be in their project. If the code is in the library you are providing via NuGet, something must still trigger this code to run, e.g. some other registration call from the user's library.

Govert
  • 16,387
  • 4
  • 60
  • 70
  • Thanks Govert. I did try the second approach, adding an `open MyNugetPackageNS` (or even `open MyNugetPackageNS.MyNugetModule`) statement to the Nuget package user code but it did not seem to produce any effect. Just in case I added an `[]` attribute to the `type MakeAddInsVisible` above, but this did not work either. What would be the right way to "trigger this code to run" in F#? – Janthelme Jun 20 '20 at 09:55
  • @Janthelme If there is no entry in the add-in's .dna file, then I don't think that library will be processed by the default registration mechanism. – Govert Jun 20 '20 at 14:34
0

Following Govert's first suggestion, I added <ExternalLibrary Path="MyNugetPackageNS.dll" ExplicitExports="true" ExplicitRegistration="true" LoadFromBytes="false" Pack="false" IncludePdb="false" /> to the package user's .dna file, and it worked.

Janthelme
  • 989
  • 10
  • 23