Weve examined quite a few COM+ issues so far in this chapter. However, most of the discussion has focused on the ways in which COM+ combines older technology and makes it easier to use. The following sections describe issues specific to COM+. Well discuss the applications you can create, special error-handling considerations, and even a special security class you need to know about.
Unlike previous renditions of COM, COM+ supports the idea of a true application type. An application type, in this case, isnt the same as the application types you associate with a client machine. For example, there are no database or spreadsheet application types when talking about COM+. Heres a list of the four COM+ application types:
Part of the reason for this new direction is that COM+ handles each kind of application differently. For example, COM+ handles the security of a library application differently than the security of a server application. When working with a library application, the object executes in the client process and the component relies on the clients security context. On the other hand, a server application executes out of process. A combination of the component attributes and the client information supplied as part of the component request define the security context.
The following sections will help you better understand how the four application types differ . You need to know about the various COM+ application types to determine what type of application you want to develop.
The server application is an out-of-process server. It executes in its own process and creates its own context. You can access all COM+ services using a server application, and the full resources of the host machine are at your disposal (within the scope of the security settings at least).
Youll create the server application more often than any other COM+ application type because this is the most versatile form of application. Obviously, this application will execute on the server and produce the least amount of network traffic (if you optimize it that way).
A library application represents one of the newest ways to integrate components in an application. The library application executes in the client process. This means that while the library application file physically resides on the server and the server must request its services, the resulting object will execute on the client machine. The client downloads a library application from the server and uses it locally.
Because of the way a library application executes, COM+ places restrictions on the way you can work with it and the services you can access. These restrictions make sense when you think about the client orientation of the library application. Heres a list of the restrictions:
No remote access support
Cant use CLB
Cant use Queued Components
Library applications can use role-based security. However, the client applications access limits the level of access for a library application. In other words, you cant create a component that will provide the client application with more access than it would normally get with its standard security settings. This limitation makes it impossible for a rogue component to damage the system or for users to pry into areas of the server they have no right seeing.
So, what are some of the advantages of library applications compared to standard client-side components? You get most of the same advantages that you would for a COM+ application, but from a client-side perspective. For example, youll still make component updates at the server, not at the client machine. The server, not the client, still secures access to the component. In fact, the client wont see a copy of the component on diskthe component resides on the server and loads into the clients memory. In short, using library applications allows you to get the best benefits of client-side components without many of the problems that client-side components pose.
When working with DCOM, you had to either use the DCOMCnfg utility (Component Services console for Windows XP users) to configure the client machine to access the remote application, or find some method to add the required registry entries through a remote application. Not only was this a difficult and error-prone process, but it required some amount of administrator time for each new client and each new version of the component. In short, the old methodology was time consuming and almost unsafe from an application perspective.
COM+ provides the proxy application type. This isnt a component but a proxy for a component registered on the server. The proxy application runs on the client machine and automatically adds information into the registry about the real component that resides on the server. This component information includes class identification (CLSIDs), program identification (ProgIDs), the remote server name (RemoteServerName), and marshalling information. This combination of entries will allow the client to access the component on the server without additional intervention on the part of the administrator or developer. In short, Microsoft has automated what could otherwise be a time-consuming and error-prone task in COM+.
COM+ comes with a group of preinstalled applications. Some developers might think these applications are for COM+ use onlymany Windows services in the past have worked exactly this way. The opposite is true with COM+youre now encouraged to use these preinstalled components to make your own programming job easier.
Youll find all the COM+ applications in the COM+ Applications folder of the Component Services console. The number of applications you see partly depends on which optional services you install. For example, there are components related to Queued Components within this folder. Heres a list of the potential COM+ Applications folder entries:
COM+ QC Dead Letter Queue Listener
IIS In-Process Applications
IIS Out-Of-Process Packed Application
IIS System Applications
Error handling is a special concern for .NET developers using COM+ because COM+ presents a few special issues. The How to Design COM Components for Use with .NET section of Chapter 3 recommended using the HRESULT value as a means of indicating an error occurred within the component. This technique works fine in only a few cases when working with COM+. In many cases, an HRESULT value wont do much for you because the client application might not even be present to receive the error. COM is a local technology, whereas COM+ is a distributed technology, which makes the developers task of error handling more difficult. You can use the HRESULT method if you know the client is going to be present to receive the return value. Otherwise, you need to find another method of error handling and reporting.
First you should try to avoid an extensive requirement for error handling. You need to create components that can recover from as many errors as possible so that error reporting isnt a significant issue. For example, the component should include code for a reasonable number of retries on a database connection before it reports an error. Likewise, it should contain code for internally handling as many resource errors as possible.
You will need to implement some form of error reporting because even a robust component will run into error conditions it cant handle. You could exercise a number of solutions, but the most practical solution is to place an error message in the Event Log to indicate the component experienced a problem. Of course, this creates uncertainty as to when, if ever, someone will actually find the error. The problem for many servers is that the administrator never looks at the Event Log as long as the server is still functional. Adding an email message to the error reporting routine cures this problem.
For every good solution, theres usually a good problem. The Event Log and email message solution suffers from a problem of information overload if the component fails drastically and produces an avalanche of error messages. Placing a limit on the number of error messages a component can generate within a given timeframe can help, but the administrator might still find a pile of messages in his or her inbox. Obviously, there are other solutions to the problem of error reporting for COM+ applications, but the use of the Event Log coupled with an email message works best overall.
Some developers create problems with their components because theyre used to developing applications in COM. For example, a developer should never add display code to a COM+ component. The reason is simple. The server is very likely stored in a closet somewhere, and no one will ever look at it. The error message will never convey the information its supposed to provide and could actually block proper server operation. Well discuss more errors of this type as the book progresses.
Security is an important issue for any distributed application. COM+ provides a solution in the form of role-based security. You learned how to configure this kind of security in the Adding Security to a COM+ Application section of Chapter 2.
The main security interface you need to know about when creating a COM+ component is ISecurityCallContext . Youll find the functionality of this unmanaged interface in the SecurityCallContext of the EnterpriseServices namespace. Dont add a reference to the COM+ Services Type Library to your application to gain access to the ISecurityCallContext support. The IDE will allow the addition, but its important that you use the SecurityCallContext class members instead.
The SecurityCallContext class provides access to the security data for a particular component in a particular context. What this means to you as a developer is that you determine what role the current user is in and what his or her rights are. The fact that this interface is for a particular context means you can work only with the request associated with this particular instance of the component. In addition, you wont be able to gain information about the component as a whole.
This interface is normally accessible to your COM+ component if the administrator enables role-based security, but you wont always need to use it. The only time youll need to use the methods of this class is when you decide to handle security within the component rather than allow the administrator to handle security as part of the components configuration.
Youll normally use the SecurityCallContext class methods to learn specific information about the current component context. All this information is contained in the security call context collection essentially an array of information about the currently executing instance of your component. Heres a list of the information that you can obtain from the security call context collection:
Number of callers
Minimum authentication level
In addition to the security call context collection information, the SecurityCallContext class helps you to determine whether a caller or user is in a specific role. Youd use this information to either grant or reject requests for access to specific methods within the component. You can also determine whether the administrator has enabled role-based security for this component (vs. being available on the server).
Now that you have a better idea of what the SecurityCallContext class can do for you, lets look at the available methods. Table 5-1 provides a list of methods youll use most often. Table 5-2 provides a list of properties associated with this class. (In most cases, the properties replace method calls used by the ISecurityCallContext interface, so you need to look at both tables for comparison.)
Determines whether the direct caller is in a specified role. This method wont list all roles the caller is in. It merely allows you to determine whether the caller is a member of the role you specify. You can use this method to determine whether a caller should have access to a specific method or resource within the component.
Performs essentially the same task as IsCallerInRole , but for a specific user. The difference between the caller and a user is that the caller is the one currently using the component. The user call can refer to any user who has access to the servernot necessarily the user making the current call.
This property returns one or more SecurityCallers objects. Each object describes a specific caller in the list of callers to the component method. Consider this a paper-trail property. This property accesses the Callers item in the ISecurityCallContext collection in COM+.
This static property obtains a SecurityCallContext object for the current call. Essentially, this is your gateway for gaining access to the information provided by the ISecurityCallContext interface.
This property returns the SecurityIdentity object for the direct caller of this method. The direct caller is the last caller in the caller hierarchy list. Use this property to determine whether the last caller in the list has the proper rights to request access to the component. If not, theres little point in continuing to process the request.
This property determines whether the administrator has enabled role-based security for this instance of the component. The method wont determine whether the administrator has enabled role-based security for other instances of the component.
This property returns the security information for the least secure caller in the caller hierarchy. By examining this property, you can determine whether any caller in the caller chain lacks proper credentials for component access.
This property returns the number of callers in the caller list. It accesses the NumCallers item in the ISecurityCallContext collection in COM+.
This property returns the SecurityIdentity object for the original caller of this method. The original caller is the first caller in the caller hierarchy list. Use this property to determine whether the first caller in the list has the proper rights to request access to the component. Sometimes the original caller tries to overcome security issues by hiding behind the rights of another caller.