Reusable software is not a new idea. COM, the most successful reusable software model, has been around for about eight years in one form or another. COM introduced the concept of a “component” – a reusable chunk of code that could span everything from a single function to an entire application such as Microsoft Word.
OLE was the first place most developers experienced COM. It is a set of features layered on top of COM that provided a similar kind of reuse to users. OLE enabled users to embed one kind of document inside another. In itself, this feature sounds uninteresting, but its implementation was dramatic: when a user pasted an Excel document inside a Word document, then clicked on that embedded Excel document, OLE would actually change the toolbars and menus to Excel’s.
From a developer’s perspective, COM provided code reuse by introducing several well-defined interfaces (e.g., iUnknown) that enabled development-time tools to query a component for its capabilities and expose those capabilities in the tool. The simplest way to think of this is to think of the controls exposed in the Visual Basic toolbox, which a developer could drag onto a form. Each of those controls actually represented hundreds or thousands of lines of code, easily wrapped up in a “black box,” so a developer could just call on their features.
The problem with COM from a developer’s perspective was that it required developers to write extra code to turn their business logic into a reusable component. There were many interfaces that the developer had to implement just to turn business logic into a component. On top of that, COM also forces developers to manually manage complexities such as cleaning up memory when a component is no longer being used, counting how many times a component is being used, setting up and tearing down threads and processes, and handling versioning.
You might think that forcing a developer to do all this work is fine, but it has several effects. For one thing, because it’s hard to do all this work, developers often make errors, resulting in application errors, system crashes, and the notorious “DLL Hell.” For another, writing all this extra code drastically cuts developer productivity, which leads to longer times to market.
All this is particularly true of the C++ developer writing COM components, and less so of the Visual Basic developer. VB abstracted and simplified many of the concepts of COM and became the most productive, popular development environment in the world. VB’s limitation, however, was that to achieve this high productivity, it hid some of the power of COM from the developer.
The .NET Framework, which we introduced at the PDC, automates the plumbing details of writing software, enabling developers to focus on writing business logic instead of COM plumbing.
The .NET Framework is a multi-language component development and execution environment that consists of three main parts:
· Common language runtime. Despite its name, the runtime actually has a role in a component’s development time and run time experiences. While the component is running, the runtime is responsible for managing memory allocation, starting up and killing threads and processes, enforcing security policy, as well as satisfying any dependencies that the component may have on other components. At development time, the runtime’s role changes slightly: because it automates so much (e.g., memory management), the runtime makes the developer’s experience very simple, especially when compared to COM today. In particular, features such as reflection dramatically reduce the amount of code a developer must write in order to turn business logic into a reusable component.
Runtimes are nothing new for languages: virtually every programming language has a runtime. Visual Basic is the most obvious runtime (the aptly-named VBRUN), but Visual C++ has one (MSVCRT), as do FoxPro, JScript, SmallTalk, Perl, Python, and Java. The .NET Framework’s critical role, and what really sets it apart, is that it provides a unified environment across all programming languages.
· Unified programming classes. The frameworks provide a unified, object-oriented, hierarchical, extensible set of class libraries (“APIs”) for developers to use. Today, C++ developers will use the Microsoft Foundation Classes, Java developers will use the Windows Foundation Classes, and Visual Basic developers will use VB’s APIs. Simply put, the frameworks unify the disparate frameworks Microsoft has today. The result is more than developers no longer having to learn multiple frameworks. By creating a common set of APIs across all programming languages, the .NET Framework enables cross-language inheritance, error handling, and debugging. In effect, all programming languages, from JScript to C++, become equals and developers are free to choose the language that they want to use.
· Active Server Pages+. ASP+ builds on the .NET Framework’s programming classes, providing a “Web application model” in the form of a set of controls and infrastructure that make it simple to build Web applications. Developers are exposed to a set of ASP+ controls that encapsulate common HTML user interface widgets such as text boxes, drop down menus, and so on. These controls actually run on the Web server, however, and simply project their user interface as HTML to a browser. On the server, the controls expose an object-oriented programming model that brings the richness of object-oriented programming to the Web developer. ASP+ also provides infrastructure services such as session state management and process recycling that further reduce the amount of code a developer must write and increase application reliability. ASP+ also uses these same concepts to enable developers to deliver software as a service. Using ASP+ Web Services features, ASP+ developers can simple write their business logic and the ASP+ infrastructure will be responsible for delivering that service via SOAP.
One of the primary goals of the .NET Framework was to make COM development easier. One of the hardest things about COM development was simply dealing with the COM infrastructure. Consequently, to make COM development easier, the .NET Framework automated virtually all of what developers currently think of as “COM,” including reference counting, interface description, and registration.
It’s important to note that this doesn’t mean that .NET Framework components aren’t COM components. In fact, a COM developer using Visual Studio 6.0 could call a .NET Framework component and, to the developer, it’d look like a COM component, complete with IUnknown. Conversely, a .NET Framework developer using Visual Studio .NET would see a COM component as a .NET Framework component.
There is a caveat to this relationship: COM developers must do manually many of the things that .NET Framework developers can rely on the runtime to automate for them. For example, the security of a COM component must be written manually, and its memory can’t be automatically managed, and, to install a COM component, you have to place entries in the Windows registry. For .NET Framework components, the runtime will automate these features. Components are self-describing, for example, and can therefore be installed without registering them in the Windows registry.
COM+ is the name of COM when you combine it with Microsoft Transaction Server, or MTS, and DCOM. COM+ provides a set of middle-tier-oriented services. In particular, COM+ provides process management and database and object connection pooling. In future versions, it will also provide stronger process isolation designed for application service providers – a feature called partitioning.
The COM+ services are primarily oriented toward middle-tier application development and focus on providing reliability and scalability for large-scale, distributed applications. These services are complementary to the programming services provided by the .NET Framework. The .NET Framework classes provide direct access to these component services.
You can think of COM+ providing component services for building scalable, reliable distributed middle tier applications. The .NET Framework provides language services that simplify and speed up application development and deployment.