In any comprehensive object-oriented system, the act of programming results in creation of new data types. There must be a way of organizing these types and/or their static representation as classes. This section tells you how classes are organized in Eiffel and in .NET, and how these organization methods are used together.
Eiffel classes are grouped in clusters. These clusters of classes ordinarily share some commonality of functionality or purpose. In other words,the classes in a particular cluster may provide the same sorts of capabilities or relate to a single software model. In the Eiffel Base Library there is a cluster called
list which contains classes which implement different types of lists, for example,
TWO_WAY_CIRCULAR. At an abstract level all these classes are related to the software model of the notion of "list".
list is actually a subcluster of the cluster
structures which contains clusters other than
list related to data structures other than lists. Eiffel convention dictates that a cluster should either contain classes or subclusters, but not both.
So clusters serve both to categorize and locate classes. So, class
LINKED_LIST can be described as a basic library class implementing a data structure, more particularly a list. As such, it can be found in the Base Library, in cluster
structures in subcluster
.NET Namespaces and Assemblies
In .NET, types (the language independent, compiled form of classes) are stored in "assemblies". So, we locate a type we want to use by referencing the assembly in which it resides. As .NET programmers, we think of types as being categorized by namespace. For example, we view the type
System.Windows.Forms.TextBox as the
TextBox type in the context of the windows forms namespace (
System.Windows.Forms). Particularly, this is in contrast to type
System.Web.UI.TextBox which is a
TextBox for web forms. As it relates to making .NET types usable by Eiffel, the important thing to understand is that the real .NET type name is the fully qualified type name, including the namespace. Namespaces are simply a bit of "syntactic sugar" that keeps us from having to repeat the entire type name every time we use it in source code.
.NET Assemblies Available to Eiffel
When types from .NET assemblies are made available to Eiffel programmers, each assembly is mapped to a cluster. So all the types in an assembly appear as if they were Eiffel classes in a cluster which corresponds to the .NET assembly. To summarize, as you learned in Naming Conventions and Name Handling, unambiguous Eiffel-style names are made available for the.NET types in an assembly. The assembly is represented to Eiffel for .NET programmers as a cluster of classes. The process of name derivation is based upon a portion of the .NET type name, possibly augmented with a prefix to ensure uniqueness.
Assemblies Built with Eiffel
The object model for which Eiffel was designed differs in some ways from the .NET object model. Importantly, Eiffel supports the facilties of full, controllable multiple inheritance, and genericity, among other things, that the inherent .NET object model does not. That does not mean that these things cannot work in .NET. Indeed they can, and they make Eiffel for .NET very powerful. But, they do make things look a little different.
When you compile Eiffel for .NET, the result is a .NET assembly; either an executable system, or a library of potentially reusable data types. Because the object model for Eiffel is different from that of .NET, the assembly resulting from a compile is different in some ways.
First an assembly built using Eiffel for .NET will likely contain lots of types and interfaces. This is because as you use a class from the Eiffel libraries, say class
STRING, all the classes upon which
STRING depends (
STRING's suppliers and ancestors) must also be included in the assembly. That's because the Eiffel libraries, unlike the Microsoft .NET libraries like
System.Data, are not distributed as shared type libraries.
Another thing you may notice is that each Eiffel class you produce is represented by three entities in the assembly ... two classes and an interface. So, if you produce a class called
GUARD_DOG, then in the assembly you'd see an interface called
GuardDog, a class called
Impl.GuardDog, and a class called
Create.GuardDog. Again, this is done for reasons that concern the differences in the object models between Eiffel and .NET.
GuardDog interface is what you use when you declare an entity or variable of that type. The objects attached to that entity at runtime will be of the type
Impl.GuardDog. You create an instance of
Impl.GuardDog and attach it to an entity of type
GuardDog by calling a routine in the factory class
Create.GuardDog. The factory routines will almost always have names that begin with the word "
Make", and represent the creation routines of Eiffel the classes. So in the case of using an instance of
GuardDog from a C# class, the code would like this:
GuardDog aGuardDog = Create.GuardDog.Make(); //Create an instance
aGuardDog.RollOver(); // Apply a feature
This object creation model accounts for some of the differences between constructors in .NET and creation procedures in Eiffel. These differences will be discussed in more detail in Constructors and Creation Procedures.
Another advantage is that it provides a syntax that is similar to that used to create objects in Eiffel. An Eiffel for .NET client to the class
GUARD_DOG might use the following code to create and use an instance.
a_guard_dog: GUARD_DOG -- Declare an entity of the type
create a_guard_dog.make -- Create an instance and attach to entity
a_guard_dog.roll_over -- Apply a feature
You may have noticed in these examples that even though the type
GuardDog was compiled from an Eiffel class, when the C# client uses
GuardDog, it uses what would be considered the .NET naming convention for the type
GUARD_DOG) and the method name
roll_over). What happens here is that when assemblies are produced from Eiffel classes, by default .NET naming standards are used in the assembly.
- Parent <Conventions>