Last Updated:

The .NET framework and magic of metadata.

Even if .NET could fix all the problems of the past, it would still not be enough. The constant growth of customer requirements for application functionality is one of the immutable laws of programming.

The ability of applications to work smoothly in different computer networks, due to the development of the Internet, has become an imperative. The functionality of the components must also be accessible from other machines. At the same time, none of the programmers wants to write a basic framework; all of them are eager to write applications designed to directly solve their customers' problems.

.NET Overview

.NET includes the Common Language Runtime (CLR). The common language runtime (CLR) supports managed execution, which has several advantages. Together with the Common Type System (CTS), the common language runtime (CLR) supports the interoperability of .NET languages. In addition, .NET provides a large, full-featured .NET Framework class library.

The Magic of Metadata

To solve all the problems associated with developing Windows applications, .NET must have a basic set of services that are available at any time in any programming language. To provide such services, .NET must have sufficient information about the application.

Serializing (converting to sequential) an object can serve as a simple example. Before every programmer, sooner or later, there is a problem of saving data. But why would every programmer reinvent the wheel by solving the question of how nested objects and complex data structures should be preserved? Why would every programmer understand how these objects and data are stored in different information repositories? .NET allows you to serialize an object without programmer intervention. If desired, the developer can do it independently.

To understand how objects are serialized, we'll look at the Serialize example in this chapter. We will not focus on the programming techniques used. These will be discussed later. For now, we're going to focus on the concepts used in this example.

fusing <mscorlib.dll
fusing <System.Runtime.Serialization.Formatters.Soap.dll
// <System. Lead time.
// Convert to serial form. Formatters. soap.dll
using namespace System;
// use the namespace System;
using namespace System::Collections;
// namespace usage System:: Collections;
using namespace System::10;
// namespace usage System:: I/O;
using namespace
System::Runtime:Serialization::Formatters::Soap; // namespace usage
// System:: Runtime:: Convert to serial
// shape::Formaters::Soap;
// [Serialization]
_gc class Customer
// garbage collector class Client
String *pname; // String long id; // identifier
_gc class Test
// garbage collector class
static void Main()
ArrayList *plist = new ArrayList;
Customer *pcust = new Customer; // new client
pcust › pname = "Charles Darwin"; // Charles Darwin
pcust › id = 10; // identifier
plist › Add(pcust); // Add
pcust = new Customer; // new client
pcust › pname = "Isaac Newton"; // Isaac Newton
pcust ›id=20; // identifier
plist › Add(pcust); // Add
for (int i=0; i < plist › get_Count(); i++)
Customer *pcust = // Customer
dynamic_cast<Customer _gc * // <Customer _ collector
//garbage * (plist › get_Item(i)); Console::WriteLine("{0}: {!}",
pcust › pname, _box(pcust › id)); // identifier } ~
Console::WriteLine("Saving Customer List"); // ("Saving the list of clients");
FileStream *ps = new FileStream("cust.txt", FileMode::Create); // Create
SoapFormatter *pf = new SoapFormatter; pf Serialize(ps, plist);
// Convert to serial form; ps Close();
Console::WriteLine("Restoring to New List");
// "Restore in new list");
ps = new FileStream("cust.txt", FileMode::Open); // Open
pf = new SoapFormatter();
ArrayList *plist2 =
dynamic_cast<ArrayList *
(pf › Deserialize(ps)); ps Close();
for (int i=0; i < plist › get_Count(); i++) {
Customer *pcust = // Customer
dynamic_cast<Customer _gc * // <Client _ garbage collector *
(plist › get_Item(i)); Console::WriteLine("{0}: {!}",
pcust › pname, _box(pcust › id)); // identifier } } };
void main(void) {
Test::Main(); }

We defined a Customer class with two fields: pname and id. First, the program creates an instance of the collection in which instances of the Customer class will be stored. We add two Customer objects to the collection, and then print the contents of the collection. The collection is then saved to disk. It is restored to a new collection instance and printed. The printed data will now be identical to the data that was printed before saving the collection [Installing the sample programs that accompany this workbook should create a ready-to-run example. If it is missing, double-click the Visual Studio .NET solution file that has a .sin extension. When Visual Studio opens, press CTRL+F5 to build and run the sample.].

If you run the application and open the resulting cust .txt file, you'll see that it contains data in an unusual XML format known as the Simple Object Access Protocol (SOAP). This protocol is specifically designed for storing and transmitting objects.

We did not write code to specify how the fields of the Customer object are saved or restored. But we defined the format (SOAP) and created an environment in which the data was then stored. The classes in the .NET Framework library are grouped so that each choice—the environment, format, and method of loading (restoring) or saving an object—can be made independently of each other. This type of class split exists in the .NET Framework library everywhere.

The Customer class has a Serializable attribute. Similarly, the name field has a public attribute. When you don't want an object to be converted to a sequential form, don't assign an attribute to it. if you try to save an object that does not have the serializable attribute an exception will occur and the program will fail [Select the serializable attribute in the program as a comment and see what happens. you can use the C and C++ syntax to enter the program to enter a comment. that is, use pairs of characters /* and */ as the opening and closing chains of the comment.].

When programming in .NET, attributes can be applied universally. By using attributes, you can describe how the .NET Framework class library handles code and data. You can also use attributes to specify the security model to use. Attributes can be used to synchronize multithreaded processing using a wireframe. Through the use of attributes, the idea of placing objects remotely becomes apparent.

To specify that an object can be persisted and recovered by the .NET Framework library, the compiler adds the Serializable attribute to the metadata of the Customer class. Metadata is additional information about code and data that is contained in the . NET application. Metadata that is a characteristic of the common language runtime (CLR) can also contain other information about the code, including:

  • Version number and local information (region, language)
  • All types used
  • details about each type, including its name. scope, etc.;
  • detailed information about the members of each type, in particular the methods used by them, the signatures of the methods, etc.;
  • Attributes.

Metadata is stored with the program code, and not in some central repository like the system registry in the Windows operating system. The way they are stored does not depend on the programming language used. Thanks to all this. NET applications contain self-descriptions. During application execution, a metadata request can be issued to obtain information about the code (for example, the presence or absence of the Serializacle attribute (Convertible to Sequential Form, Ordered)). You can extend the metadata by adding your own attributes.

In our example, the .NET Framework library can request metadata to obtain information about the structure of the Customer object, which is then used to save and restore the object.