• No results found

Configuring containers with XML

In document Manning Dependency Injection in .NET (Page 100-102)

A comprehensive example

3.2 Configuring DI Containers

3.2.1 Configuring containers with XML

When DI CONTAINERS first appeared back in the early 2000s, they all used XML as a con- figuration mechanism—most things did back then. Much experience with XML as a configuration mechanism has later revealed that this is rarely the best option.

XML tends to be verbose and brittle. When you configure a DI CONTAINER in XML, you identify various classes and interfaces, but you have no compiler support to warn you if you misspell something. Even if the class names are correct, there’s no guaran- tee that the required assembly is going to be in the application’s probing path.

The advantage of XML configuration is that you can change the behavior of the application without recompilation. This is valuable if you develop software that ships to thousands of customers because it gives them a way to customize the application. However, if you write an internal application or a website where you control the deployment environment, it’s often easier to just recompile and redeploy the applica- tion when you need to change the behavior.

Table 3.2 Configuration options

Style Description Advantages Disadvantages

XML Configuration settings (often in .config files) specify the mappings.

Supports replacement without recompilation High degree of control

No compile-time checks Verbose

CODEAS CONFIGURATION

Code explicitly deter- mines mappings.

Compile-time checks High degree of control

No support for replace- ment without recompila- tion

AUTO-REGISTRATION Rules are used to locate suitable components and build the mappings.

Supports replacement without recompilation Less effort required Helps enforce conventions to make a code base more consistent

Partial compile-time checks

Less control

3 For a good overview article on Convention over Configuration, see Jeremy Miller, “Patterns in Practice: Conven-

tion Over Configuration,” (MSDN Magazine, February 2009). Also available online at http://msdn.microsoft .com/en-us/magazine/dd419655.aspx

69

Configuring DI Containers

TIP Use XML configuration only in those cases where you actively wish to sup- port late binding. Prefer CODE AS CONFIGURATION or AUTO-REGISTRATION in all

other cases.

A DI CONTAINER is often configured with XML by pointing it at a particular XML file, but sometimes it can also pick up the configuration from the application configura- tion file. The following example uses the latter option.

EXAMPLE: CONFIGURINGTHESAMPLECOMMERCEAPPLICATIONWITH XML

Because the Unity container is one of the more XML-centric of the DI CONTAINERS cov-

ered in this book, it makes sense to use it for an example of XML configuration. In this example, you’ll configure the sample commerce application from section 2.3. A large part of the task is to apply the configuration outlined in table 3.1, but you must also supply a similar configuration to support composition of the Home- Controller class. The following listing shows the configuration necessary to get the application up and running.

<register type="IBasketService" mapTo="BasketService" /> <register type="BasketDiscountPolicy" mapTo="RepositoryBasketDiscountPolicy" /> <register type="BasketRepository" mapTo="SqlBasketRepository"> <constructor> <param name="connString"> <value value="CommerceObjectContext" typeConverter="ConnectionStringConverter" /> </param> </constructor> </register> <register type="DiscountRepository" mapTo="SqlDiscountRepository"> <constructor> <param name="connString"> <value value="CommerceObjectContext" typeConverter="ConnectionStringConverter" /> </param> </constructor> </register> <register type="ProductRepository" mapTo="SqlProductRepository"> <constructor> <param name="connString"> <value value="CommerceObjectContext" typeConverter="ConnectionStringConverter" /> </param> </constructor> </register> <register type="CurrencyProvider" mapTo="SqlCurrencyProvider">

Listing 3.1 Configuring Unity with XML

Simple mapping

b

Specify connection string

c

<constructor> <param name="connString"> <value value="CommerceObjectContext" typeConverter="ConnectionStringConverter" /> </param> </constructor> </register>

As you can see from even this simple code listing, XML configuration tends to be quite verbose. Simple mappings like the one from the IBasketService interface to the BasketService class

B

are easily expressed with a simple register element.

However, as you may recall, some of the concrete classes take a connection string as input, so you need to specify how the value of this string is found

c

. With Unity, you can do that by indicating that you use a custom type converter called Connection- StringConverter. This converter will look up the value CommerceObjectContext among the standard web.config connection strings and return the connection string with that name.

The rest of the elements repeat these two patterns.

Because Unity can automatically resolve requests for concrete types even if there are no explicit registrations, you don’t need to supply XML elements for Home- Controller and BasketController.

Loading the configuration into the container is done with a single method call:

container.LoadConfiguration();

The LoadConfiguration method loads the XML configuration from listing 3.1 into the container. With the configuration in place, the container can now resolve requests for HomeController, and so on.

Other DI CONTAINERS also support XML configuration. The exact XML schema is different for each container, but the overall structure tends to be similar.

WARNING As your application grows in size and complexity, so will your con- figuration file if you use configuration-based composition. It can grow to become a real stumbling block because it models coding concepts such as classes, parameters, and such, but without the benefits of the compiler, debug- ging options, and so forth. Configuration files will tend to become brittle and opaque to errors, so only use this approach when you need late binding.

Because of the disadvantages of verbosity and brittleness, you should prefer the other alternatives for configuring containers. CODEAS CONFIGURATION is similar to XML con- figuration in granularity and concept, but obviously uses code instead of XML.

In document Manning Dependency Injection in .NET (Page 100-102)