By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,645 Members | 1,065 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,645 IT Pros & Developers. It's quick & easy.

COM+ Singletons & instances ?

P: n/a
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:]
Nov 22 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
"Angelos Karantzalis" <ak**********@yahoo.com> wrote:
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 ?
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: ApplicationActivation(ActivationOption.Server)]
[ObjectPooling(MinPoolSize=1,
MaxPoolSize=1,CreationTimeout=20000)]
[JustInTimeActivation(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.
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 ?
???
Are you alluding to maintaining a client-specific state
within the server object?

In general don't. Make "chunky" calls.Cheers,
Angel
O:]


Nov 22 '05 #2

P: n/a
Hmmm .. i think some re-phrasing is in order ....
Issue 1:

public class MyDatabaseConnectionInfo - 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
MyDatabaseConnectionInfo. 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
MyDatabaseConnectionInfo in-memory. No matter how many MyLittleDAOs exist, I
want all of them to work with that single instance. If the
MyDatabaseConnectionInfo 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" <nu**@null.null> wrote in message
news:u5********************************@4ax.com...
"Angelos Karantzalis" <ak**********@yahoo.com> wrote:
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 aSingleton ?

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: ApplicationActivation(ActivationOption.Server)]
[ObjectPooling(MinPoolSize=1,
MaxPoolSize=1,CreationTimeout=20000)]
[JustInTimeActivation(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.
Ideally, I'd like to have the wrappers pooled, but only one singleton helperin memory because it's a very memory-hungry object that contains an xml filedata about 200K. If it's not a singleton, then for 100 COMDbWrappers I have100*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 ?


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

In general don't. Make "chunky" calls.
Cheers,
Angel
O:]

Nov 22 '05 #3

P: n/a
"Angelos Karantzalis" <ak**********@yahoo.com> wrote:
Hmmm .. i think some re-phrasing is in order ....
Issue 1:

public class MyDatabaseConnectionInfo - 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
MyDatabaseConnectionInfo. That way, it can operate on different
datasources on different occasions.

Both components are present under the same COM+ Application.
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
What I'd like to do, is a l w a y s have a single instance of
MyDatabaseConnectionInfo in-memory.
- What scope of memory?
- application domain?
- machine?
No matter how many MyLittleDAOs exist, I
want all of them to work with that single instance. If the
MyDatabaseConnectionInfo implements the Sigleton design pattern (you know,
static GetInstance() and the like), will it actually exist only once in
memory ?
You still haven't specified how the ES app is configured; do
you specify

[assembly: ApplicationActivation(ActivationOption.Server)]

or

[assembly: ApplicationActivation(ActivationOption.Library)]

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 MyDatabaseConnectionInfo Singleton in
the client's application domain.
- but every client app has its own instance of
MyDatabaseConnectionInfo - 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
MyDatabaseConnectionInfo 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

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 ?
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 IMySecurityManager Interface
using ServicedComponent1;
using ServicedComponent2:

....

IMySecurityManager FirstSecMgr =
new ServicedComponent1.SecurityManager(
Parm11, Parm12, Parm13
);
IMySecurityManager SecondSecMgr =
new ServicedComponent2.SecurityManager(
Parm21, Parm22, Parm23, Parm24, Parm25
);

I hope this is clearer now :]

Cheers,
Angel
O:]

Nov 22 '05 #4

P: n/a
Issue 1:

public class MyDatabaseConnectionInfo - 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
MyDatabaseConnectionInfo. That way, it can operate on different
datasources on different occasions.

Both components are present under the same COM+ Application.
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


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


What I'd like to do, is a l w a y s have a single instance of
MyDatabaseConnectionInfo in-memory.


- What scope of memory?
- application domain?
- machine?


ES App. Domain. or IIS App domain.
That means:
- there is only one MyDatabaseConnectionInfo Singleton in
the client's application domain.
- but every client app has its own instance of
MyDatabaseConnectionInfo - so there are as many instances as
there are clients.
It's library app. IIS threads are considered different clients ? What i need
is a single instance serving a single IIS App.

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 includeit on several COM+ Applications on the same
machine, how can I specify from the client side which COM+ ApplicationI'm calling to ?


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 IMySecurityManager Interface
using ServicedComponent1;
using ServicedComponent2:

...

IMySecurityManager FirstSecMgr =
new ServicedComponent1.SecurityManager(
Parm11, Parm12, Parm13
);
IMySecurityManager SecondSecMgr =
new ServicedComponent2.SecurityManager(
Parm21, Parm22, Parm23, Parm24, Parm25
);


... 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:]
Nov 22 '05 #5

P: n/a
"Angelos Karantzalis" <ak**********@yahoo.com> wrote:

>What I'd like to do, is a l w a y s have a single instance of
>MyDatabaseConnectionInfo in-memory.
- What scope of memory?
- application domain?
- machine?


ES App. Domain. or IIS App domain.


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).
That means:
- there is only one MyDatabaseConnectionInfo Singleton in
the client's application domain.
- but every client app has its own instance of
MyDatabaseConnectionInfo - so there are as many instances as
there are clients.
It's library app. IIS threads are considered different clients?


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
ServicedComponent are intercepted at COM+ context
boundaries. These objects are called context-bound. Calls to
instances of classes that do not derive from
ServicedComponent 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
ServicedComponent."

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).
What i need
is a single instance serving a single IIS App.
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.
>
>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 Iinclude >it on several COM+ Applications on the same
> machine, how can I specify from the client side which COM+Application >I'm calling to ?


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 IMySecurityManager Interface
using ServicedComponent1;
using ServicedComponent2:

...

IMySecurityManager FirstSecMgr =
new ServicedComponent1.SecurityManager(
Parm11, Parm12, Parm13
);
IMySecurityManager SecondSecMgr =
new ServicedComponent2.SecurityManager(
Parm21, Parm22, Parm23, Parm24, Parm25
);


.. 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 :)


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.

Cheers,
Angel
O:]


Nov 22 '05 #6

P: n/a
LT
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
IObjectConstruct 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 SharedPropertyManager
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
ls**@wjaltd.com
"Angelos Karantzalis" wrote:
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:]

Nov 22 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.