COM+ Singletons & instances ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Angelos Karantzalis

    #1

    COM+ Singletons & instances ?

    Hi y'all ...

    I'm a bit puzzled here about .NET class instancing under COM+

    Issue 1:

    I've a COM+ component, let's call it ... COMDbWrapper that initializes
    itself from an xml file.
    The data in the file change very rarely, so I would like to keep it in a
    single copy in-memory if that's possible.
    Towards that goal, the COMDbWrapper uses a Singleton helper in it's
    constructor, so that if a helper instance exists, no other instances are
    created for the same xml file.

    My question is ... will that work under COM+ ??? Do all instances of the
    COMDbWrapper use a shared VM [oops! CLR :D ], and is my Singleton actually a
    Singleton ?

    Ideally, I'd like to have the wrappers pooled, but only one singleton helper
    in memory because it's a very memory-hungry object that contains an xml file
    data about 200K. If it's not a singleton, then for 100 COMDbWrappers I have
    100*200K memory consumption, but I'm thinking I only consume a mere 200K ...
    which would appear very stupid on my behalf, & I'd like to avoid that :D

    Issue 2:

    How can I have the same COM+ component under two different COM+
    Applications, and differentiate in the caller's code [ or the client app.
    configuration ] which instance I want to serve my call ?

    Cheers,
    Angel
    O:]


  • UAError

    #2
    Re: COM+ Singletons & instances ?

    "Angelos Karantzalis" <akarantzalis@y ahoo.com> wrote:
    [color=blue]
    >Hi y'all ...
    >
    >I'm a bit puzzled here about .NET class instancing under COM+
    >
    >Issue 1:
    >
    >I've a COM+ component, let's call it ... COMDbWrapper that initializes
    >itself from an xml file.
    >The data in the file change very rarely, so I would like to keep it in a
    >single copy in-memory if that's possible.
    >Towards that goal, the COMDbWrapper uses a Singleton helper in it's
    >constructor, so that if a helper instance exists, no other instances are
    >created for the same xml file.
    >
    >My question is ... will that work under COM+ ??? Do all instances of the
    >COMDbWrapper use a shared VM [oops! CLR :D ], and is my Singleton actually a
    >Singleton ?
    >[/color]
    Relax. The term Virtual Machine (VM) has been heavily in use
    since Smalltalk has the the light of day - and as such is
    appropriate if not very .NET centric. Though MS is bend on
    turning their VM into an OS.

    Anyway, the only way you can have a Singleton in Enterprise
    Services is to configure it to have a pool size minimum and
    maximum of one. If you also configure it for Just In Time
    Activation (JITA) the object will not be destroyed
    (retaining its own internal state) and just handed to the
    next caller.

    When you are using the term "Singleton" here, are you
    talking about a Enterprise Component configured in this
    manner (.i.e. the singleton and COMDbWrapper are separate ES
    applications ) or are you talking about the singleton
    implementation pattern?

    Of course to configure an ES app as a singleton you'll have
    to run it as a server application rather than a library
    application.

    [assembly: ApplicationActi vation(Activati onOption.Server )]
    [ObjectPooling(M inPoolSize=1,
    MaxPoolSize=1,C reationTimeout= 20000)]
    [JustInTimeActiv ation(true)]

    Multiple objects can hold references to this singleton but
    of course only one is able to access it at a time.

    Your COMDbWrapper could just be a Library Application - if
    you don't need ES support (e.g. transactions) you may just
    want to make it a regular non-serviced component.
    [color=blue]
    >Ideally, I'd like to have the wrappers pooled, but only one singleton helper
    >in memory because it's a very memory-hungry object that contains an xml file
    >data about 200K. If it's not a singleton, then for 100 COMDbWrappers I have
    >100*200K memory consumption, but I'm thinking I only consume a mere 200K ...
    >which would appear very stupid on my behalf, & I'd like to avoid that :D
    >
    >Issue 2:
    >
    >How can I have the same COM+ component under two different COM+
    >Applications , and differentiate in the caller's code [ or the client app.
    >configuratio n ] which instance I want to serve my call ?[/color]

    ???
    Are you alluding to maintaining a client-specific state
    within the server object?

    In general don't. Make "chunky" calls.[color=blue]
    >Cheers,
    >Angel
    >O:]
    >[/color]

    Comment

    • Angelos Karantzalis

      #3
      Re: COM+ Singletons &amp; instances ?

      Hmmm .. i think some re-phrasing is in order ....


      Issue 1:

      public class MyDatabaseConne ctionInfo - loads DB connection info &
      metadata for several (plenty!!!) databases.

      public class MyLittleDAO - handles inserts/deletes/selects for some
      business object, using the datasources described in
      MyDatabaseConne ctionInfo. That way, it can operate on different
      datasources on different occasions.

      Both components are present under the same COM+ Application.

      What I'd like to do, is a l w a y s have a single instance of
      MyDatabaseConne ctionInfo in-memory. No matter how many MyLittleDAOs exist, I
      want all of them to work with that single instance. If the
      MyDatabaseConne ctionInfo implements the Sigleton design pattern (you know,
      static GetInstance() and the like), will it actually exist only once in
      memory ?

      Issue 2:

      public class SecurityManager - it handles aythentication &
      authorisation, using dynamic class creation to create an
      adapter to a user datasource, be it LDAP, Active Directory, RDBMS or
      XML. This is a component that cries-out
      "re-use" and it will work for many of my projects. BUT ... if I include
      it on several COM+ Applications on the same
      machine, how can I specify from the client side which COM+ Application
      I'm calling to ?

      I hope this is clearer now :]

      Cheers,
      Angel
      O:]


      "UAError" <null@null.null > wrote in message
      news:u5c6q0t8g6 ir7rb08b731dmqt 42jel4b8q@4ax.c om...[color=blue]
      > "Angelos Karantzalis" <akarantzalis@y ahoo.com> wrote:
      >[color=green]
      > >Hi y'all ...
      > >
      > >I'm a bit puzzled here about .NET class instancing under COM+
      > >
      > >Issue 1:
      > >
      > >I've a COM+ component, let's call it ... COMDbWrapper that initializes
      > >itself from an xml file.
      > >The data in the file change very rarely, so I would like to keep it in a
      > >single copy in-memory if that's possible.
      > >Towards that goal, the COMDbWrapper uses a Singleton helper in it's
      > >constructor, so that if a helper instance exists, no other instances are
      > >created for the same xml file.
      > >
      > >My question is ... will that work under COM+ ??? Do all instances of the
      > >COMDbWrapper use a shared VM [oops! CLR :D ], and is my Singleton[/color][/color]
      actually a[color=blue][color=green]
      > >Singleton ?
      > >[/color]
      > Relax. The term Virtual Machine (VM) has been heavily in use
      > since Smalltalk has the the light of day - and as such is
      > appropriate if not very .NET centric. Though MS is bend on
      > turning their VM into an OS.
      >
      > Anyway, the only way you can have a Singleton in Enterprise
      > Services is to configure it to have a pool size minimum and
      > maximum of one. If you also configure it for Just In Time
      > Activation (JITA) the object will not be destroyed
      > (retaining its own internal state) and just handed to the
      > next caller.
      >
      > When you are using the term "Singleton" here, are you
      > talking about a Enterprise Component configured in this
      > manner (.i.e. the singleton and COMDbWrapper are separate ES
      > applications ) or are you talking about the singleton
      > implementation pattern?
      >
      > Of course to configure an ES app as a singleton you'll have
      > to run it as a server application rather than a library
      > application.
      >
      > [assembly: ApplicationActi vation(Activati onOption.Server )]
      > [ObjectPooling(M inPoolSize=1,
      > MaxPoolSize=1,C reationTimeout= 20000)]
      > [JustInTimeActiv ation(true)]
      >
      > Multiple objects can hold references to this singleton but
      > of course only one is able to access it at a time.
      >
      > Your COMDbWrapper could just be a Library Application - if
      > you don't need ES support (e.g. transactions) you may just
      > want to make it a regular non-serviced component.
      >[color=green]
      > >Ideally, I'd like to have the wrappers pooled, but only one singleton[/color][/color]
      helper[color=blue][color=green]
      > >in memory because it's a very memory-hungry object that contains an xml[/color][/color]
      file[color=blue][color=green]
      > >data about 200K. If it's not a singleton, then for 100 COMDbWrappers I[/color][/color]
      have[color=blue][color=green]
      > >100*200K memory consumption, but I'm thinking I only consume a mere 200K[/color][/color]
      ....[color=blue][color=green]
      > >which would appear very stupid on my behalf, & I'd like to avoid that :D
      > >
      > >Issue 2:
      > >
      > >How can I have the same COM+ component under two different COM+
      > >Applications , and differentiate in the caller's code [ or the client app.
      > >configuratio n ] which instance I want to serve my call ?[/color]
      >
      > ???
      > Are you alluding to maintaining a client-specific state
      > within the server object?
      >
      > In general don't. Make "chunky" calls.[color=green]
      > >Cheers,
      > >Angel
      > >O:]
      > >[/color]
      >[/color]


      Comment

      • UAError

        #4
        Re: COM+ Singletons &amp; instances ?

        "Angelos Karantzalis" <akarantzalis@y ahoo.com> wrote:
        [color=blue]
        >Hmmm .. i think some re-phrasing is in order ....
        >
        >
        >Issue 1:
        >
        > public class MyDatabaseConne ctionInfo - loads DB connection info &
        >metadata for several (plenty!!!) databases.
        >
        > public class MyLittleDAO - handles inserts/deletes/selects for some
        >business object, using the datasources described in
        > MyDatabaseConne ctionInfo. That way, it can operate on different
        >datasources on different occasions.
        >
        >Both components are present under the same COM+ Application.[/color]

        An ES app does not "talk" to multiple applications at the
        same time; either
        - there is a separate instance talking to each client
        app or
        - the same one(s) talk to the client apps in turn[color=blue]
        >
        >What I'd like to do, is a l w a y s have a single instance of
        >MyDatabaseConn ectionInfo in-memory.[/color]

        - What scope of memory?
        - application domain?
        - machine?
        [color=blue]
        >No matter how many MyLittleDAOs exist, I
        >want all of them to work with that single instance. If the
        >MyDatabaseConn ectionInfo implements the Sigleton design pattern (you know,
        >static GetInstance() and the like), will it actually exist only once in
        >memory ?[/color]

        You still haven't specified how the ES app is configured; do
        you specify

        [assembly: ApplicationActi vation(Activati onOption.Server )]

        or

        [assembly: ApplicationActi vation(Activati onOption.Librar y)]

        in your assembly.cs?

        Currently I suspect that you do neither with means that the
        ES app is running (be default) as an in-process library.
        That means:
        - there is only one MyDatabaseConne ctionInfo Singleton in
        the client's application domain.
        - but every client app has its own instance of
        MyDatabaseConne ctionInfo - so there are as many instances as
        there are clients.

        If you want a single configured component on the entire
        machine to control a single resource then you must implement
        MyDatabaseConne ctionInfo as a separate ES application

        - activate it as a server
        - Create an object pool of min/max 1;
        - Specify JITA to keep it alive between requests.

        this will however impair scalability of your application as
        a whole.

        MyLittleDAO should reside in a separate component. Whether
        that component should be serviced depends on whether you
        need to have transactions span multiple requests - if you do
        not, don't bother implementing it as a serviced component
        (i.e. no separate ES/COM+ app necessary).


        Be advised that MS warns against the above practice in:

        Chapter 8 — Improving Enterprise Services Performance
        http://msdn.microsoft.com/library/de...netchapt08.asp

        "Avoid object pooling if you need only one object in your
        pool. Instead, investigate the singleton object model
        supported by .NET remoting."


        Implementing Broker with .NET Remoting Using
        Server-Activated Objects
        http://msdn.microsoft.com/library/de...okerServer.asp


        Applied Remoting
        http://msdn.microsoft.com/library/de...et05272003.asp
        [color=blue]
        >
        >Issue 2:
        >
        > public class SecurityManager - it handles aythentication &
        >authorisatio n, using dynamic class creation to create an
        > adapter to a user datasource, be it LDAP, Active Directory, RDBMS or
        >XML. This is a component that cries-out
        > "re-use" and it will work for many of my projects. BUT ... if I include
        >it on several COM+ Applications on the same
        > machine, how can I specify from the client side which COM+ Application
        >I'm calling to ?[/color]

        If you are talking about two separate ES Apps rather than
        two instances of the same ES app then that's easy - that is
        what namespaces are for.

        // To foster reuse have all versions of SecurityManager
        // implement the same IMySecurityMana ger Interface
        using ServicedCompone nt1;
        using ServicedCompone nt2:

        ....

        IMySecurityMana ger FirstSecMgr =
        new ServicedCompone nt1.SecurityMan ager(
        Parm11, Parm12, Parm13
        );
        IMySecurityMana ger SecondSecMgr =
        new ServicedCompone nt2.SecurityMan ager(
        Parm21, Parm22, Parm23, Parm24, Parm25
        );
        [color=blue]
        >
        >I hope this is clearer now :]
        >
        >Cheers,
        >Angel
        >O:][/color]

        Comment

        • Angelos Karantzalis

          #5
          Re: COM+ Singletons &amp; instances ?

          [color=blue][color=green]
          > >Issue 1:
          > >
          > > public class MyDatabaseConne ctionInfo - loads DB connection info &
          > >metadata for several (plenty!!!) databases.
          > >
          > > public class MyLittleDAO - handles inserts/deletes/selects for some
          > >business object, using the datasources described in
          > > MyDatabaseConne ctionInfo. That way, it can operate on different
          > >datasources on different occasions.
          > >
          > >Both components are present under the same COM+ Application.[/color]
          >
          > An ES app does not "talk" to multiple applications at the
          > same time; either
          > - there is a separate instance talking to each client
          > app or
          > - the same one(s) talk to the client apps in turn[/color]

          The "client" of the ES App. is a Web App hosted on the local IIS. The ES
          App. runs as a library.

          [color=blue][color=green]
          > >
          > >What I'd like to do, is a l w a y s have a single instance of
          > >MyDatabaseConn ectionInfo in-memory.[/color]
          >
          > - What scope of memory?
          > - application domain?
          > - machine?[/color]

          ES App. Domain. or IIS App domain.
          [color=blue]
          > That means:
          > - there is only one MyDatabaseConne ctionInfo Singleton in
          > the client's application domain.
          > - but every client app has its own instance of
          > MyDatabaseConne ctionInfo - so there are as many instances as
          > there are clients.[/color]

          It's library app. IIS threads are considered different clients ? What i need
          is a single instance serving a single IIS App.
          [color=blue]
          >[color=green]
          > >
          > >Issue 2:
          > >
          > > public class SecurityManager - it handles aythentication &
          > >authorisatio n, using dynamic class creation to create an
          > > adapter to a user datasource, be it LDAP, Active Directory, RDBMS or
          > >XML. This is a component that cries-out
          > > "re-use" and it will work for many of my projects. BUT ... if I[/color][/color]
          include[color=blue][color=green]
          > >it on several COM+ Applications on the same
          > > machine, how can I specify from the client side which COM+[/color][/color]
          Application[color=blue][color=green]
          > >I'm calling to ?[/color]
          >
          > If you are talking about two separate ES Apps rather than
          > two instances of the same ES app then that's easy - that is
          > what namespaces are for.
          >
          > // To foster reuse have all versions of SecurityManager
          > // implement the same IMySecurityMana ger Interface
          > using ServicedCompone nt1;
          > using ServicedCompone nt2:
          >
          > ...
          >
          > IMySecurityMana ger FirstSecMgr =
          > new ServicedCompone nt1.SecurityMan ager(
          > Parm11, Parm12, Parm13
          > );
          > IMySecurityMana ger SecondSecMgr =
          > new ServicedCompone nt2.SecurityMan ager(
          > Parm21, Parm22, Parm23, Parm24, Parm25
          > );[/color]

          ... but that's no re-use at all ... the code inside the SecurityManager
          implementation creates an "Adapter" object dynamically - from config data -
          to talk to LDAP, RDBMS etc. the core Security Manager code is always the
          same. I don't want to re-use an interface ... :? I want to have the same
          SecurityManager dll in seperate ES Apps, and pick the one I want to talk to.
          I can't believe that no-one has ever used the same dll in two separate ES
          Apps, so there must be a way :)

          Cheers,
          Angel
          O:]


          Comment

          • UAError

            #6
            Re: COM+ Singletons &amp; instances ?

            "Angelos Karantzalis" <akarantzalis@y ahoo.com> wrote:

            [color=blue][color=green][color=darkred]
            >> >What I'd like to do, is a l w a y s have a single instance of
            >> >MyDatabaseConn ectionInfo in-memory.[/color]
            >>
            >> - What scope of memory?
            >> - application domain?
            >> - machine?[/color]
            >
            >ES App. Domain. or IIS App domain.[/color]

            Nothing in .Net is supposed to run inside the IIS Process
            (which is a high privilege system process) the ASP.NET
            worker process (asp_wp.exe) is responsible for managing
            ASP.NET applications and Web services. In (2003 Server) IIS
            6.0 you have the option of multiple, separately configured
            Worker processes.

            As a library the ES component executes in the clients
            process (which really belongs to the CLR not the client .NET
            application)

            As a server the ES component has its own process (usually
            run by dllhost.exe IFAIK).
            [color=blue]
            >[color=green]
            >> That means:
            >> - there is only one MyDatabaseConne ctionInfo Singleton in
            >> the client's application domain.
            >> - but every client app has its own instance of
            >> MyDatabaseConne ctionInfo - so there are as many instances as
            >> there are clients.[/color]
            >
            >It's library app. IIS threads are considered different clients?[/color]

            I presume you're talking about the worker process, not IIS.
            The documentation is a bit fuzzy on that. MTS/COM+ was
            developed before the notion of application domains, so its
            always stated the library will run in the client process.
            However the CLR or any .NET host will always run multiple
            application domains in the same process - and I'm not clear
            whether the CLR will manage a single copy of the library for
            multiple application domains - somehow I doubt it - but I
            don't know.

            Given that the Run-time host will try to keep the memory of
            the application domains seperate I suspect that you will
            have multiple versions of your "Singleton" it there are
            multiple application domains using it.

            On the other hand

            "COM+ Integration: How .NET Enterprise Services Can Help You
            Build Distributed Applications"
            http://msdn.microsoft.com/msdnmag/is...s/default.aspx

            may suggest that runtime actually only keeps one copy of the
            library around:

            "First, calls to instances of classes that derive from
            ServicedCompone nt are intercepted at COM+ context
            boundaries. These objects are called context-bound. Calls to
            instances of classes that do not derive from
            ServicedCompone nt are not intercepted at COM+ context
            boundaries. These objects are called context-agile. CLR
            objects are always context-agile by default. They only
            become context-bound when you derive from
            ServicedCompone nt."

            In any case, you would be safer to expose your "single
            point" of access as a Windows Service and implement it as a
            singleton remoting object (accessing it only locally of
            course).
            [color=blue]
            >What i need
            >is a single instance serving a single IIS App.[/color]

            If all instances of the app always run in the same worker
            process AND the runtime host keeps only a single copy of the
            ES component at hand, you should be fine - for now. If your
            application runs on a multi-processor machine and separate
            processors run different instances of the same app - then
            you are going to end up with synchronization issues.
            [color=blue][color=green]
            >>[color=darkred]
            >> >
            >> >Issue 2:
            >> >
            >> > public class SecurityManager - it handles aythentication &
            >> >authorisatio n, using dynamic class creation to create an
            >> > adapter to a user datasource, be it LDAP, Active Directory, RDBMS or
            >> >XML. This is a component that cries-out
            >> > "re-use" and it will work for many of my projects. BUT ... if I[/color][/color]
            >include[color=green][color=darkred]
            >> >it on several COM+ Applications on the same
            >> > machine, how can I specify from the client side which COM+[/color][/color]
            >Application[color=green][color=darkred]
            >> >I'm calling to ?[/color]
            >>
            >> If you are talking about two separate ES Apps rather than
            >> two instances of the same ES app then that's easy - that is
            >> what namespaces are for.
            >>
            >> // To foster reuse have all versions of SecurityManager
            >> // implement the same IMySecurityMana ger Interface
            >> using ServicedCompone nt1;
            >> using ServicedCompone nt2:
            >>
            >> ...
            >>
            >> IMySecurityMana ger FirstSecMgr =
            >> new ServicedCompone nt1.SecurityMan ager(
            >> Parm11, Parm12, Parm13
            >> );
            >> IMySecurityMana ger SecondSecMgr =
            >> new ServicedCompone nt2.SecurityMan ager(
            >> Parm21, Parm22, Parm23, Parm24, Parm25
            >> );[/color]
            >
            >.. but that's no re-use at all ... the code inside the SecurityManager
            >implementati on creates an "Adapter" object dynamically - from config data -
            >to talk to LDAP, RDBMS etc. the core Security Manager code is always the
            >same. I don't want to re-use an interface ... :? I want to have the same
            >SecurityManage r dll in seperate ES Apps, and pick the one I want to talk to.
            >I can't believe that no-one has ever used the same dll in two separate ES
            >Apps, so there must be a way :)[/color]

            There are more levels of re-use than I would care to
            count...and a lot of them include interfaces, especially if
            you are trying to avoid God-Components, which you should at
            all cost - so by your description I was imagining a unifying
            interface that was implemented by different classes that may
            share some subcomponents in their composition, and maybe
            even an abstract superclass.

            Anyway, I can't see where you see the problem. Each ES
            component can use the same assembly. To expose the object to
            the client simply provide a factory method on each ES
            component.
            [color=blue]
            >
            >Cheers,
            >Angel
            >O:]
            >[/color]

            Comment

            • LT

              #7
              RE: COM+ Singletons &amp; instances ?

              Hi,
              Hope this can help,
              I have encountered similar issue about re-using COM+ componenet in different
              apps (Issue2). I had been going through some research and just found in COM+
              Service Management Console (XP or above), you can actually configure the one
              same component (class) in one dll into different Lib/Svr packages by using
              the Alias... context menu. But this will actually create new ProgID as
              CopyOf.[OrigProgID] in those aliased package - I guess because registry
              requires unique ProgID.
              This would still need the client code to call each specific object with
              different ProdID, but you don't need to recoding object. Plus you can use
              IObjectConstruc t for customization.

              Or could be more issues?
              I faced similar issue as issue2. I configured my server pkg to have Identity
              that can use Windows Authentication to access DB with SharedPropertyM anager
              holding ConnString. That works fine. When I need to use same data access dll
              for different client, I want to use data access code in-proc so that I don't
              have to configure different server packages. But that does not work.
              When I use it in-proc withour putting in COM+ services, I am calling those
              COM (no+) component from .NET, does it still run in DLLHOST.exe?
              Is that unmanaged code running in .NET AppDomain in this case?

              LT
              Thanks for any help
              lsun@wjaltd.com


              "Angelos Karantzalis" wrote:
              [color=blue]
              > Hi y'all ...
              >
              > I'm a bit puzzled here about .NET class instancing under COM+
              >
              > Issue 1:
              >
              > I've a COM+ component, let's call it ... COMDbWrapper that initializes
              > itself from an xml file.
              > The data in the file change very rarely, so I would like to keep it in a
              > single copy in-memory if that's possible.
              > Towards that goal, the COMDbWrapper uses a Singleton helper in it's
              > constructor, so that if a helper instance exists, no other instances are
              > created for the same xml file.
              >
              > My question is ... will that work under COM+ ??? Do all instances of the
              > COMDbWrapper use a shared VM [oops! CLR :D ], and is my Singleton actually a
              > Singleton ?
              >
              > Ideally, I'd like to have the wrappers pooled, but only one singleton helper
              > in memory because it's a very memory-hungry object that contains an xml file
              > data about 200K. If it's not a singleton, then for 100 COMDbWrappers I have
              > 100*200K memory consumption, but I'm thinking I only consume a mere 200K ...
              > which would appear very stupid on my behalf, & I'd like to avoid that :D
              >
              > Issue 2:
              >
              > How can I have the same COM+ component under two different COM+
              > Applications, and differentiate in the caller's code [ or the client app.
              > configuration ] which instance I want to serve my call ?
              >
              > Cheers,
              > Angel
              > O:]
              >
              >
              >[/color]

              Comment

              Working...