with a specific ponent。 You knew which type to instantiate; which interface to use; and which project to reference。 In these cases; you; as the developer; are in plete control; and when your application is built; all of the assemblies pop out as a nice; neat package。 But what works for the developer might not necessarily work for others。 Let’s go back to the lighting system presented in Chapter 8。 We created a kernel that was responsible for turning on and off the lights。 The implementations of the individual rooms were in a predetermined project with a specific name。 This architecture would not work with a third…party library; because the kernel expected a project of a certain name。 You might be thinking; “Heck; that’s easy to solve—I just delete the old project and rename my project to match the old name。” That tech nique would work; but it would also be an administrator’s nightmare。 The solution is to tell the program; “For lighting room implementations; look at this project and these types。” And to give the program this information; you define some text in a file。 A file that tells a program to do some task is called a runtime configuration file。 This chapter focuses on two areas: using application configuration files and dynamically loading code。 A related topic is how much dynamically executed code should be configuration and how much should be convention。 Convention over Configuration The question of how to reference and instantiate classes is both philosophical and pragmatic。 Consider the architecture shown in Figure 12…1; which is a modular interface and implementation that was presented as an alternative architecture for the lighting system example in Chapter 8。 In this figure; each of the boxes represents a single project: a project that contains the interface definitions; a project that contains the implementations; and a project that contains the kernel。 The idea of all of these projects is to make it possible to update a single project without needing to update all of them。 However; what is not indicated in the picture is the fact that your appli cation must be able to reference all three projects。 If one of those projects is missing; you have a problem; because your program cannot function。 313 …………………………………………………………Page 336…………………………………………………………… 314 CH AP T E R 1 2 ■ L E A R N I N G A B OU T A PP L I CA TI O N CO N F I G U R AT IO N AN D D Y N A M I C L O AD I N G Figure 12…1。 How ponents can be defined The referencing of individual projects is not an issue。 The issue is how each project learns about the others。 In previous chapters; I said that you should use a factory; because a factory takes away the decision of what implementation to use。 Let’s look at this from the perspective of code。 Suppose the following interface definition is in a project that contains all interface definitions。 Public Interface IMyInterface End Interface A class that implements the interface is defined in a project called Implementations。 Class MyImplementation : Implements IMyInterface End Class If a class in another project wants to use the functionality of MyImplementation; then this factory is created: Public Module Factory Public Function Instantiate() As IMyInterface Return New MyImplementation() End Function End Module Because MyImplementation is not declared as Public; the Factory module must be defined in the project Implementations。 This implies that the project that uses the functionality has a reference to Implementations。 …………………………………………………………Page 337…………………………………………………………… CH AP T E R 1 2 ■ L E AR N IN G AB O U T AP P L I CAT I ON CO N F IG U R AT IO N A N D D Y N A M IC L O AD IN G 315 Using a factory is acceptable and solves the problem of decoupling so that the user of the implementation does not need to know about the implementation。 The user does not have to know the name of the implementation; but does need to know in which project the implemen tation resides。 This means when you develop the code; you need to reference the appropriate project while coding。 This is called ponent architecture; in that you decouple the interface from the implementation; but you couple the projects。 You want to decouple the ponents at runtime (when the application runs) to solve the problem illustrated in Chapter 8; where we created a lighting kernel; but did not know the lighting implementations ahead of time。 Using configuration; you could have an end user “plug in” lighting implementations that are controlled by the kernel。 Developers like to call runtime decoupling a plug…in architecture ( http://en。wikipedia。org/wiki/Plugin)。 And this is where configuration and convention e into play。 “Convention over configuration” is a Ruby on Rails philosophy。 The idea is that developers define only the nonconventional parts of their applications。 Decoupling Using a Configuration Architecture In a runtime configuration scenario; the architecture of Figure 12…1 is not altered; it still has the definitions; implementations; kernel; and user assemblies。 What is altered is how the references to each of the pieces are created。 Let’s start with a simple situation。 You have a question; and you happen to know who would know the answer。 You know the person and you know she has a telephone。 What you don’t know is her telephone number。 Translated into programming terms; the telephone acts as an interface