# Introducing CodeConfig

## A Dependency Injection Example

We will introduce the new code based approach by working with a very simple application that will provide us the context to understand the concepts of CodeConfig. We start by examining a sample application that uses Spring.NET configured via ‘traditional’ XML configuration files. Then we show how CodeConfig can be used to achieve the same results without any XML configuration files at all.

To begin with, let’s explore the sample application that we will be working with. This sample app is included in the Spring.NET CodeConfig download package in the `/examples/Spring.CodeConfig.Migration` folder.

To keep things simple, it’s just a .NET console application designed to calculate and display the prime numbers between zero and an arbitrary maximum number. There are four classes that must collaborate together to do the work: `ConsoleReporter`, `PrimeGenerator`, `PrimeEvaluationEngine`, and `OutputFormatter`. `ConsoleReporter` depends on the `PrimeGenerator` which in turn depends on the `PrimeEvaluationEngine` to calculate the prime numbers. `ConsoleReporter` also depends on `OutputFormatter` to format the results. The main console application then simply asks `ConsoleReporter` to write its report and `ConsoleReporter` goes to work. The following Figure is a UML class diagram showing a simple way to visualize the dependencies between these objects.

A simple `Main()` method that would do this without the Spring.NET container could look something like Listing 1. Note the in-line injection of dependencies via constructor arguments that builds up the collaborating objects.

    //Listing 1 (sample Main method not using Spring.NET)
    static void Main(string[] args)
    {
         ConsoleReport report = new ConsoleReport(
                                  new OutputFormatter(),
                                  new PrimeGenerator(new PrimeEvaluationEngine()));

         report.MaxNumber = 1000;
         report.Write();

         Console.WriteLine("--- hit enter to exit --");
         Console.ReadLine();
    }

Using Spring.NET, as opposed to manually injecting dependencies as in Listing 1, the collaborating objects are composed together with their dependencies injected by the Spring.NET container at run-time. Initially, the configuration of these objects is controlled from a Spring.NET XML configuration file (see Listing 2).

    <!-- Listing 2 (Spring.NET XML Configuration file, application-context.xml) -->
    <?xml version="1.0" encoding="utf-8" ?>
    <objects xmlns="http://www.springframework.net">

      <object name="ConsoleReport" type="Primes.ConsoleReport, Primes">
        <constructor-arg ref="PrimeGenerator"/>
        <constructor-arg ref="OutputFormatter"/>
        <property name="MaxNumber" value="1000"/>
      </object>

      <object name="PrimeGenerator" type="Primes.PrimeGenerator, Primes">
        <constructor-arg>
          <object type="Primes.PrimeEvaluationEngine, Primes"/>
        </constructor-arg>
      </object>

      <object name="OutputFormatter" type="Primes.OutputFormatter, Primes"/>

    </objects>

In Listing 2 you can also see the use of “`ref`” element to refer to collaborating objects and the property “`MaxNumber`” being set to “`1000`” on the `ConsoleReport` object after it’s constructed. This is the maximum number up to which we want the software to calculate prime numbers. In Listing 3 we see the construction of the `XmlApplicationContext` which is initialized by passing it the name of the XML Configuration file. This container is then used to resolve the `ConsoleReport` object with all of its dependencies properly satisfied and its `MaxNumber` property assigned the value of `1000`.

    //Listing 3 (initializing the XmlApplicationContext container)
    static void Main(string[] args)
    {
         IApplicationContext ctx = CreateContainerUsingXML();

         ConsoleReport report = ctx["ConsoleReport"] as ConsoleReport;
         report.Write();

         ctx.Dispose();

         Console.WriteLine("--- hit enter to exit --");
         Console.ReadLine();
    }

    private static IApplicationContext CreateContainerUsingXML()
    {
         return new XmlApplicationContext("application-context.xml");
    }

While this XML-based configuration is well-understood by Spring.NET users and others alike as a common method for expressing configuration settings, it suffers from several challenges common to all XML file including being overly-verbose and full of string-literals that are unfriendly to most of the modern refactoring tools.

## Migration to CodeConfig

To reduce or even eliminate the use of XML for configuring the Spring.NET DI container, let’s look at how we can express the same configuration metadata in code using Spring.NET CodeConfig. There are several steps to using CodeConfig. We will look at each of them in the likely sequence that one would follow to convert an existing XML-based configuration for Spring.NET over to use the CodeConfig approach.

### The CodeConfig Classes

#### Creating the CodeConfig Classes

First, we need to construct one or more classes to contain our configuration metadata and attribute them properly. Spring.NET CodeConfig relies upon attributes applied to classes and methods to convey its metadata. Shown in Listing 4 is the CodeConfig class (`PrimesConfiguration`) for our sample application.

    // Listing 4, (Spring.NET Configuration Class, PrimesConfiguration.cs)
    using System;
    using System.Configuration;
    using Primes;
    using Spring.Context.Attributes;

    namespace SpringApp
    {
        [Configuration]
        public class PrimesConfiguration
        {
            [ObjectDef]
            public virtual ConsoleReport ConsoleReport()
            {
                ConsoleReport report = new ConsoleReport(OutputFormatter(), PrimeGenerator());

                report.MaxNumber = Convert.ToInt32(ConfigurationManager.AppSettings.Get("MaximumNumber"));
                return report;
            }

            [ObjectDef]
            public virtual IOutputFormatter OutputFormatter()
            {
                return new OutputFormatter();
            }

            [ObjectDef]
            public virtual IPrimeGenerator PrimeGenerator()
            {
                return new PrimeGenerator(new PrimeEvaluationEngine());
            }
        }
    }

#### Elements of the CodeConfig Classes

Let’s explore the important elements of the CodeConfig file in Listing 4 to understand how it can convey the same information to the Spring.NET container as the XML file in Listing 2.

##### The Class

At the class level, you will notice the `PrimesConfiguration` class has the`[Configuration]` attribute applied to it. During the initialization phase of the DI container, Spring.NET CodeConfig reads classes with these attributes. Note that there is no specific inheritance hierarchy required of a configuration class: no special base class or interface implementation is required, leaving you free to leverage inheritance and polymorphism to achieve some interesting configuration and composition scenarios. Also note these special identifying attributes are only applied to your CodeConfig classes, not the types for which they are providing object definition metadata. This means that your classes that do the work of your application (e.g., `ConsoleReport`, `PrimeGenerator`, etc.) are free to remain undiluted POCO (Plain-Old-CLR-Object) classes that have themselves no direct dependency on the Spring.NET framework.

##### The Methods

At the member level of the `PrimesConfiguration` class, you will notice several methods having the `[ObjectDef]` attribute. This attribute identifies the method to which it is applied as being the logical representation of a single object definition for the Spring.NET container.

To begin understanding how this works let’s look at the simplest of the definitions, that of the OutputFormatter. Let’s start with the method visibility: all `[ObjectDef]` methods must be declared both public and virtual.

###### Why must the [ObjectDef] methods be virtual?

The requirement for the `[ObjectDef]` methods being virtual comes from the need when using CodeConfig for the container to proxy `[ObjectDef]` methods on the `[Configuration]` classes. When the container is asked for an object, this proxy intercepts the invocation of the `[ObjectDef]` methods and ensures that requests for objects respect object scoping rules like singleton and prototype. Singleton scope ensures that if you ask the container multiple times for the same named object, it will always return the same instance rather than a new one each time. Singleton scope is common in server-side programming and is the default lifecycle in Spring.NET.

The method return type, `IOutputFormatter`, becomes the type that the DI container will be configured to register. The method name itself, `OutputFormatter`, is the equivalent of the id or name that will be assigned to the object in the container. This name can also be controlled by setting the `Names` property on the `[ObjectDef]` attribute itself.

The body of the `OutputFormatter()` method simply creates a new instance of the `OutputFormatter` and returns it. In simple terms, we can think of the`OutputFormatter()` method as a factory method that knows how to construct and return an instance of something that implements the `IOutputFormatter` interface (in this case, the concrete `OutputFormatter` class).

##### More Complex Methods

To understand a slightly more complex `[ObjectDef]` method, let’s now examine the `PrimeGenerator()` method. Given what we already know about CodeConfig, it’s easy to see that the `PrimeGenerator()` method describes an Object Definition that will be registered with the container under the name “`PrimeGenerator`” (the method name) and the type `IPrimeGenerator` (the return type of the method).

The method needs to return a new `PrimeGenerator` but unlike the `OutputFormater` class that offers an empty default constructor, the `PrimeGenerator` class’ only public constructor requires an instance of the `PrimeEvaluationEngine` class be passed to it. To satisfy this constructor dependency, we simply create a new `PrimeEvaluationEngine` object in-line and pass it to the new `PrimeGenerator` class. In this way, the dependency between `PrimeGenerator` and `PrimeEvaluationEngine` is satisfied in much the same way as when coded ‘by hand’ as shown in Listing 1.

As a slightly more complex `[ObjectDef]` example, let’s examine the `ConsoleReport()` method next. This method needs to return a new `ConsoleReport` instance, but as with the `PrimeGenerator` class we lack a zero-argument public constructor. The only public constructor of the `ConsoleReport` class requires an `IOutputFormatter` instance and an `IPrimeGenerator` instance be provided. In our call to new up an instance of the `ConsoleReport` class in the `ConsoleReport()` `[ObjectDef]` method, we are invoking the other `[ObjectDef]` methods themselves to return these types. Since these other methods in turn return `IOutputFormatter` and `IPrimeGenerator` instances respectively, calls to these other methods will satisfy the constructor dependency of the `ConsoleReport` class and thus permit us to create a new `ConsoleReport` to return at the end of the `ConsoleReport()` method itself. In this manner, we are delegating from one `[ObjectDef]` method to the other `[ObjectDef]` methods to create the object graph that we seek to return from the call to the `ConsoleReport()` method.

##### Controlling Properties on Objects

But what about the “`MaxNumber`” property that is set for the `ConsoleReport` object in the XML file in Listing 2? As you can see from Listing 4, setting this property on our `ConsoleReport` object is as simple as…well, setting the property on our `ConsoleReport` object! Since our `ConsoleReport()` method merely has to return a new `ConsoleReport` instance, we are completely free to use any approach (in code) we choose to modify the `ConsoleReport` instance before we return it. In this case, it’s a simple matter of reading the value out of the `App.Config` file and then setting the property to the desired value before we return the instance of the `ConsoleReport` object from the method.

### Creating and Initializing the Application Context

Once we have translated the XML configuration file in Listing 2 into the CodeConfig class in Listing 4, we need to tell our application to use it. For that, we need to switch from encapsulating our container in the Spring.NET `XmlApplicationContext` to encapsulating it in the `CodeConfigApplicationContext` instead. Just as the `XmlApplicationContext` is designed to use XML as the initial entry point to its configuration settings, the `CodeConfigApplicationContext` is designed to scan assemblies for `[Configuration]` classes and `[ObjectDef]` methods as the initial entry point to its configuration settings. Listing 5 shows the`CreateContainerUsingCodeConfig()` method from the `Program.cs` file in the sample application that demonstrates this process.

    //Listing 5 (bootstrapping the CodeConfigApplicationContext from Program.cs)
    private static IApplicationContext CreateContainerUsingCodeConfig()
    {
        CodeConfigApplicationContext ctx = new CodeConfigApplicationContext();
        ctx.ScanAllAssemblies();
        ctx.Refresh();
        return ctx;
    }

After instantiating the `CodeConfigApplicationContext`, we next invoke the `ScanAllAssemblies()` method to perform the scanning for the `[Configuration]`-attributed classes and `[ObjectDef]`-attributed methods within our project. Lastly, the container is initialized by calling the `Refresh()` method and then the ready-to-use context is returned from the method. In the invocation of the `ScanAllAssemblies()` method, we are asking the `CodeConfigApplicationContext` to scan the current AppDomain’s root folder and all subfolders recursively for all assemblies that might contain CodeConfig classes (classes having the `[Configuration]` attribute).

## More Granular Control Using CodeConfig

The example in Listing 4 and Listing 5 demonstrates only the most basic use-cases for CodeConfig. More granular control over each of the definitions is provided by applying additional attributes to the `[Configuration]` classes and `[ObjectDef]` methods and by setting various values on these attributes. Among these are the following:

- `[Scope]` for controlling object lifecycle settings on a `[ObjectDef]` such as singleton, prototype, etc.

- `[Import]` for chaining `[Configuration]` classes together so that you can logically divide your `[ObjectDef]` methods among multiple classes in much the same way you may do so with multiple XML files that provide pointers to other XML files

- `[ImportResource]` for combining `[Configuration]` classes with any of Spring.NET’s many implementations of its `IResource` abstraction (file://, assembly://, etc.), the most common one being an XML resource so that you can define part of your configuration metadata in `[Configuration]` classes and other parts of it in XML files as either embedded resource(s) in your assemblies or as file(s) on disk.

- `[Lazy]` for controlling lazy instantiation of singleton objects

- If you require aliases (additional, multiple names) for the Type in the container, the `[ObjectDef]` attribute also accepts an array of strings that if provided will be registered as aliases for the Type registration.

In addition, finer-grained control of the specific assemblies to scan, and specific `[Configuration]` classes to include and/or exclude is supported by the scanning API. It is also possible to compose configurations by dividing your `[ObjectDef]` methods into multiple different `[Configuration]` classes and then to assemble them as building blocks to configure your container as it is initialized.

The CodeConfig approach enables us to express the same configuration metadata to our Dependency Injection container as the XML file in Listing 2 had provided, but in a form that is at once both significantly more powerful and flexible as well as more resilient to the refactoring our container-managed application objects.

To address additional common non-XML configuration scenarios, such as the XML schemas for AOP and Transaction management, Spring.NET is also evolving a more fluent-style configuration API that will build upon CodeConfig in even more flexible ways in the near future including convention-based registration of objects.

## Organizing and Composing Multiple [Configuration] Classes

The examples referenced in this document and provided in this distribution almost all employ merely a single [Configuration] class from which their ApplicationContext is to be configured. For these simple examples this approach is viable but just as is the case when configuring the ApplicationContext via XML, any significantly complex solution is likely to require separating your [ObjectDef] methods into multiple [Configuration] classes.

Just as there are several strategies for effectively managing multiple XML configuration files, so too are there many options available to the developer to organize and compose multiple [Configuration] classes together in a larger solution. This section doesn't attempt to cover all of the available options in deep detail, but is intended to provide a high-level understanding of some of the techniques that can be combined together to help manage multiple such classes. Users familair with the common techniques for composing together multiple XML configuration files for Spring.NET will recognize some of these same patterns applied to [Configuration] classes in the following sections as well.

### Multiple Stand-Alone Configuration Classes

The simplest organization approach is providing multiple stand-alone [Configuration] classes. In this scenario, [ObjectDef] methods are organized into separate [Configuration] classes but each of the [Configuration] classes is entirely self-contained and unrealted to the others. The decomposition principles can of course be anything of your choosing. One simple possibility might be to divide your configuration data between different kinds of services as in the following example:

    [Configuration]
    public class WcfServicesConfigurations
    {
         [ObjectDef]
         public virtual IWebService MySpecialService()
         {
              //construct and return a IWebService implementation here
         }
    }

    [Configuration]
    public class RepositoryServicesConfigurations
    {
         [ObjectDef]
         public virtual ICustomerRepository MyCustomerRepository()
         {
              //construct and return a ICustomerRepository implementation here
         }

         [ObjectDef]
         public virtual IShippingRepository MyShippingRepository()
         {
              //construct and return a IShippingRepository implementation here
         }
    }

In this example, both of these `[Configuration]` classes would need to be explicitly scanned and registered with the `CodeConfigApplicationContext` since they each are completely stand-alone and both are needed for the proper configuration of the ApplicationContext. Since these two classes in this example have no interdependencies between them, each class may be placed into a different file or even assembly.

### High-Level [Configuration] Classes that [Import] Others

Another strategy for composing multiple `[Configuration]` classes together is to devise one or more 'high-level entry-point' classes and leverage the `[Import]` attribute so that the scanning of the high-level class automatically imports one or more lower-level classes. The high-level classes may contain [ObjectDef] methods of their own or merely hold reference to one or more [Import] classes as needed.

    [Configuration]
    [Import(typeof(MyWebServicesConfigurations))]
    [Import(typeof(MyMessagingServicesConfigurations))]
    [Import(typeof(MyPersistenceServicesConfigurations))]
    public class ServicesConfigurations
    {
         //rest of class here as needed
    }

In this example, only the `ServicesConfigurations` class needs to be scanned because the `[Import]` attributes point directly to the other classes to scan for `[Configuration]` and `[ObjectDef]` metadata.

### Referencing [ObjectDef]s from one [Configuration] Class in Another

Once you decompose your `[ObjectDef]` methods into separate classes, often you will find that you have a need to reference the objects defined in one `[Configuration]` class when coding the `[ObjectDef]` methods in another `[Configuration]` class. The architecture of Spring CodeConfig for .NET makes it simple to address this need: you can simply ask the ApplicationContext to resolve the needed Type.

To understand how this works, its first important to understand that `[Configuration]` classes are themselves registered as types in the ApplicationContext in addition to the types defined in their `[ObjectDef]` methods. Combining that knowledge with the special `IApplicationContextAware` interface in Spring.NET allows us to ask the ApplicationContext to inject itself into our `[Configuration]` classes. This ApplicationContext is then available to us to resolve requests for needed types that may be defined elsewhere, whether in other `[Configuration]` classes or perhaps even other XML files.

Let's explore the following example where the `SecondConfiguration` class needs access to the `TransactionManager` that is defined in the `FirstConfiguration` class in order to properly build and configure a `CustomerRepository` instance:

    [Configuration]
    public class FirstConfiguration
    {
         [ObjectDef]
         public virtual TransactionManager MySpecialTransactionManager()
         {
              return new TransactionManager();
         }
    }

    [Configuration]
    public class SecondConfiguration : IApplicationContextAware //note the interface implementation
    {
         //field to hold the injected context
         private IApplicationContext _context;

         //property setter defined by the IApplcationContextAware interface
         //     so that the context can inject itself into the class
         public IApplicationContext ApplicationContext { set { _context = value; } }

         [ObjectDef]
         public virtual ICustomerRepository CustomerRepository()
         {
              //to construct the CustomerRepository, we need a TransactionManager instance
              //     as a constructor argument so let's ask the injected context to resolve one for us
              return new CustomerRepository(_context.GetObject<TransactionManager>());
         }
    }

    //somewhere else in your solution the CustomerRepository class is defined as follows...
    public class CustomerRespository : ICustomerRespository
    {
         private TransactionManager _transactionManager;

         public CustomerRespository(TransactionManager transactionManager)
         {
              _transactionManager = transactionManager;
         }
    }

In this way, there is no direct coupling between `[Configuration]` classes and the SecondConfiguration class is only aware of the ApplicationContext itself and the actual Types it needs to construct the Types described in its `[ObjectDef]` methods.