- Build time. Program source is compiled into components or deployment units during build time. Components are not a priori committed to either specific programming language constructs (such as classes), or granularity. Moreover, a component might also contain other resources and constant data beyond code (such as bitmap graphics). To enable reuse beyond source sharing, the build process must be able to refer to metadata attached to previously built components (details later in this article). To enable independent extensibility, the build process must be able to create individual componentsnot just closed applications.
- Load time. Components are loaded into an execution environment at load time, yielding an executable image. Metadata in a loaded unit indicates static dependencies on other units. The loader has to check whether these are already loaded and, if not, locate and load these as well. (A loader's strategy may vary depending on how lazily or how eagerly the resolution of such dependencies is performed.)
- Runtime. Executables are run at runtime. Like loading, execution might cause transitive building, loading, and subsequent execution of other components demanded dynamically by executing code.
This is of course a simplification of real life where a program might go through design time, link time, JIT time, and so forth, but that would only clutter the presentation at this point. The important issue is that in each of these phases, names have to be bound to values, and that these bindings might change when transitioning between binding times. The C# fragment shown in Figure 1 defines a class X, and then creates instances of that class X, and of two other classes Y and Z. The instance-creating statements rest on a spectrum of binding times. The use of type X can be resolved at build time; the reference to the externally defined type Y will be resolved at load time, while the type named "Z" is resolved at runtime.
Reuse beyond source sharing and independent extensibility has several consequences for how to name components, and how names on the level of program source are mapped onto names of components.
|