Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 4094746
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 20, 20262026-05-20T19:47:11+00:00 2026-05-20T19:47:11+00:00

I have an Addin for MS Excel which needs a singleton to share data

  • 0

I have an Addin for MS Excel which needs a singleton to share data amongst modules.
Depending on the version of Excel (2003, 2007, 2010), and how Excel was started, it calls my addin from different, unpredictable AppDomains, which prevents the classic singleton approach.

Creating a custom AppDomainManager won’t work because Excel has already created the AppDomains before the addin is called.

Linking to mscoree to enumerate domains breaks the addin registration process (and I really don’t want that anyway); there doesn’t seem to be any other way of enumerating, so that isn’t an option either.

The only solution that I’ve found is to use remoting. Here’s my test rig:

Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
' Remeber to add reference to System.Runtime.Remoting DLL !

Public Class CrossAppDomainSingleton(Of T As {New})
    Inherits MarshalByRefObject

    Private Const _portnumber As Integer = 9999 ' adjust to suit taste
    Private Shared _instance As T = Nothing
    Private Shared _lock As Object = New Object
    Private Shared _id As Guid = Nothing
    Private Shared _myapp As String = System.Reflection.Assembly.GetExecutingAssembly().GetName.Name
    Private Shared _myname As String = GetType(T).ToString
    Private Shared _myfullname As String = _myapp & "/" & _myname

    Protected Sub New()
        _id = Guid.NewGuid
        Console.WriteLine("New " & ID & " in " & AppDomain.CurrentDomain.FriendlyName)
    End Sub
    Public Function GetInstance() As T
        If _instance Is Nothing Then
            Console.WriteLine("GetInstance in " & AppDomain.CurrentDomain.FriendlyName)
            _instance = New T
        End If
        Return _instance
    End Function
    Public ReadOnly Property ID As String
        Get
            Return _id.ToString
        End Get
    End Property
    Public Overrides Function InitializeLifetimeService() As Object
        Console.WriteLine("InitializeLifetimeService=infinite")
        Return Nothing
    End Function
    Public Shared Function Instance() As T

        Dim currentdomain As AppDomain
        Dim uri As String
        Dim registered As Boolean = False
        Dim remotet As Object
        Dim tcpchannel As Tcp.TcpChannel
        Dim tcpprops As System.Collections.IDictionary
        Dim sw As Stopwatch = New Stopwatch

        Try
            sw.Start()
            SyncLock _lock
                Console.WriteLine("Instance in " & AppDomain.CurrentDomain.FriendlyName)
                If _instance Is Nothing Then
                    currentdomain = AppDomain.CurrentDomain
                    _instance = currentdomain.GetData(_myfullname)

                    If _instance Is Nothing Then

                        ' Build connection string "tcp://localhost:[_portnumber]/[myapp]/[myname]".
                        uri = String.Format("tcp://localhost:{0}/{1}/{2}",
                                            _portnumber.ToString,
                                            _myapp,
                                            _myname)
                        registered = False
                        Try
                            remotet = RemotingServices.Connect(GetType(T), uri)
                            _instance = remotet.GetInstance()
                            currentdomain.SetData(_myfullname, _instance)
                            registered = True
                        Catch ex As Exception
                        End Try

                        If registered Then
                            Console.WriteLine("... instanced with remoting")
                        Else
                            Try
                                Dim ichannel As IChannel = ChannelServices.GetChannel(_myfullname)
                                ChannelServices.UnregisterChannel(ichannel)
                            Catch ex As Exception
                            End Try
                            tcpprops = New System.Collections.Hashtable
                            tcpprops("port") = _portnumber.ToString
                            tcpprops("name") = _myfullname
                            tcpchannel = New Tcp.TcpChannel(tcpprops, Nothing, Nothing)
                            ChannelServices.RegisterChannel(tcpchannel, False)
                            RemotingConfiguration.ApplicationName = _myapp
                            RemotingConfiguration.RegisterWellKnownServiceType(GetType(T),
                                                                               _myname,
                                                                               WellKnownObjectMode.Singleton)
                            remotet = RemotingServices.Connect(GetType(T), uri)
                            _instance = remotet.GetInstance()
                            Console.WriteLine("... singleton instance created")
                        End If
                    Else
                        Console.WriteLine("... instanced from AppDomain")
                    End If
                Else
                    Console.WriteLine("... instanced statically")
                End If
            End SyncLock
        Catch ex As Exception
            Console.WriteLine(String.Format("Error in {0}.Instance: {1}", _myname, ex.Message))
        End Try

        Console.WriteLine("instance time=" & CLng(1000000 * sw.ElapsedTicks / Stopwatch.Frequency) & " µS")
        sw.Stop()

        Return _instance

    End Function

End Class

(please ignore the style, etc., it’s just a mockup).

I exercise it with :

Module Main
    Public Class Common
        Inherits CrossAppDomainSingleton(Of Common)
        ' real application data goes here
    End Class
    Sub Main()
        Dim common As Common
        common = common.Instance
        Dim defaultdomain As AppDomain = AppDomain.CurrentDomain
        defaultdomain.DoCallBack(AddressOf ShowSingleton)

        Dim domain1 As AppDomain = AppDomain.CreateDomain("One")
        domain1.DoCallBack(AddressOf ShowSingleton)

        Dim domain2 As AppDomain = AppDomain.CreateDomain("Two")
        domain2.DoCallBack(AddressOf ShowSingleton)

        defaultdomain.DoCallBack(AddressOf ShowSingleton)
        domain1.DoCallBack(AddressOf ShowSingleton)
        domain2.DoCallBack(AddressOf ShowSingleton)

        Dim junk As Object = Console.ReadKey
    End Sub
    Private Sub ShowSingleton()
        Console.WriteLine("ShowSingleton in " & AppDomain.CurrentDomain.FriendlyName)
        Dim common As Common = common.Instance
        Console.WriteLine("guid is " & common.ID)
    End Sub
End Module

Here are the results:

Instance in CrossAppDomainSingletonDemo.vshost.exe
New 497696b6-71c7-4001-b232-39b379034385 in CrossAppDomainSingletonDemo.vshost.exe
InitializeLifetimeService=infinite
GetInstance in CrossAppDomainSingletonDemo.vshost.exe
New 3a3a7a9c-a4f7-46d4-9b16-35fdbfbdc6c4 in CrossAppDomainSingletonDemo.vshost.exe
InitializeLifetimeService=infinite
... singleton instance created
instance time=2593865 µS ' AAAARRRRGGGGHHHHH !!!!!!!!!!!!!!
ShowSingleton in CrossAppDomainSingletonDemo.vshost.exe
Instance in CrossAppDomainSingletonDemo.vshost.exe
... instanced statically
instance time=38 µS
guid is 3a3a7a9c-a4f7-46d4-9b16-35fdbfbdc6c4
ShowSingleton in One
Instance in One
... instanced with remoting
instance time=440087 µS
guid is 3a3a7a9c-a4f7-46d4-9b16-35fdbfbdc6c4
ShowSingleton in Two
Instance in Two
... instanced with remoting
instance time=438821 µS
guid is 3a3a7a9c-a4f7-46d4-9b16-35fdbfbdc6c4
ShowSingleton in CrossAppDomainSingletonDemo.vshost.exe
Instance in CrossAppDomainSingletonDemo.vshost.exe
... instanced statically
instance time=111 µS
guid is 3a3a7a9c-a4f7-46d4-9b16-35fdbfbdc6c4
ShowSingleton in One
Instance in One
... instanced statically
instance time=106 µS
guid is 3a3a7a9c-a4f7-46d4-9b16-35fdbfbdc6c4
ShowSingleton in Two
Instance in Two
... instanced statically
instance time=105 µS
guid is 3a3a7a9c-a4f7-46d4-9b16-35fdbfbdc6c4

Once everything is running, access to the singleton takes ~100µS, which is perfect. I can live with the ~400mS the first time each AppDomain is initialised. The problem is at startup, where the remoting invocation takes ~2.5 seconds.

Any suggestions would be very welcome, I’ve been weeks trying to find a decent solution >;-)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-20T19:47:12+00:00Added an answer on May 20, 2026 at 7:47 pm

    Resolved with IPC instead of TCP

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have c# code behind my Excel-dna addin which is successfully downloading data from
I have an Excel addin application which I developed with C# and I published
I have a DLL (Test.dll) which contains some Excel Addin, i don't know which
I have code that worked in the VSTO version of an Excel Addin Microsoft.Office.Tools.Excel.ListObject
I have an Excel VSTO AddIn that I moved up to Excel 2007/VS2010 last
I have an AddIn which I want to invoke through Excel interop from a
I have Excel add-in which I add so many class modules that it is
I have a Excel COM addin which reads the CustomDocumentProperties section of a workbook.
I have a VSTO addin and I'm reading data from an Excel worksheet. It
I have the following code in VBA (which resides in an Excel 2007 Workbook):

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.