GOTCHA #70 Spattering access to COM components makes code hard to maintainAfter reviewing the gotchas in communicating from .NET to COM, you might sit back with a deep breath and say, "Hmm, what a mess. How am I going to use all these correctly in my application?" Well, let's start with how you use them incorrectly. The easiest way to fail at it is to call COM components from all over your code, as shown in Figure 8-12 (this diagram shows classes and not instances; instances of your .NET classes will talk to different instances of RCW during execution). In this figure, a number of .NET classes want to utilize a COM component. Each one of them creates an instance of RCW and interacts with it. The complexity of the application goes up in this approach for reasons mentioned below. There are several things that you need to do when interacting with COM:
Figure 8-12. Improper use of COM component in an application
How can you verify that your application follows these guidelines? One easy way to manage this complexity is to isolate access to COM components in logical wrapper classes, as shown in Figure 8-13. First, build a .NET class that exposes the intended interface(s) of the COM component to the rest of the application. From within this wrapper class, you will interact with the COM Component(s). You can carefully manage the access and lifetime of the component(s) based on their apartment, state, and resource utilization. For example, by implementing the IDisposable interface and calling ReleaseComObject() in the Dispose() method, you can take care of proper cleanup of the COM component. Likewise, you can determine the apartment needs of the COM component and launch a thread with proper apartment settings to interact with it if required. The rest of your application does not have to worry about these details. Figure 8-13. Isolation of access to COM components in an applicationThis isolation confers several benefits:
IN A NUTSHELLRoute all interaction to the RCW of a COM component through a .NET wrapper class. This isolates the problems related to interoperability and makes your code easier to maintain. SEE ALSOGotcha #65, "Release of COM object is confusing," Gotcha #66, "Using interface pointers after calling ReleaseComObject() will fail," Gotcha #67, "Cross-apartment calls are expensive," Gotcha #68, "Default apartment of main thread is inconsistent across languages," and Gotcha #69, "STAThread attribute may have no effect on your methods." |