| S2Container.NET TOP page ## S2Container.NET DI Container Introduction to S2Container (link to Java version document) What's Different? What's the Merit? S2Container.NET Reference Files that Needs to be Created Defining a S2Container Creating a S2Container Getting a Component Application Configuration File Dependency Injection Types Constructor Injection Property Injection Method Injection Dividing and Including S2Container Configuration Files Namespace Instance Management Lifecycle Automatic Binding Using S2Container from a Component S2HttpModule Role of app.dicon Applying AOP Meta data Automatic Binding of Request S2Container Definition Reference DOCTYPE components tag include tag component tag arg tag property tag meta tag initMethod tag destroyMethod tag aspect tag description tag JScript.NET expression Examples Constructor Injection Property Injection Method Injection Automatic Binding (Constructor Injection) Automatic Binding (Property Injection) ## S2Container.NET Reference ### Files that Needs to be Created SConfiguration file is required to use S2Container. Configuration file contains blue print of how components are to be built. Configuration file is a XML document with file extension dicon. ### Defining S2Container S2Container is defined as follows:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
    "http://www.seasar.org/dtd/components21.dtd">
    <components>
        <component name="..." class="...">

                ...
        </component>
        <component name="..." class="...">
                ...
        </component>
    </components>
DOCTYPE may not be omitted. When creating a dicon file, cut and paste the above sample. Root element is a component. Each component is defined by a component tag and class name is defined in a class attribute of a component tag. Component name is defined in a name attribute of a component. Refer to S2Container Definition Reference for further details.
    <components>
        <component name="hoge" class="S2.NET.Examples.Dicon.HogeImpl"/>

    </components>
### Creating a S2Container Following methods are used to create a S2Container: - S2.NET.Framework.Container.Factory.S2ContainerFactory#Create(string path) Configuration file may be specified by embedding it in resource or by using the file system. To embed the configuration file, argument path specifies complete path name including the namespace. A slash (/ character is used as a eparator between folders. Configuration file build action property should be set to the embedded resource. In C#, when a project is created, namespace is also created. In VB.NET, however, a namespace is not created when a VB.NET project is created. For example, if project folder is /Sample/Logic/aaa.dicon, C# set the default namespace /Sample/Logic/aaa.dicon to the project. In VB.NET, however, the namespace is the default namespace /aaa.dicon. To specify using a file system, absolute or relative file path to the configuration file is specified. Configuration file may also be specified by a combination of embedded and file system. When there is a conflict between the choice, file system specification takes precedence.
    private const string PATH = "aaa/bbb/ccc.dicon";
    ...
    IS2Container container = S2ContainerFactory.Create(PATH);
### Getting a Component Following method is used to get a component from the S2Container: - Argument to S2.NET.Framework.Container.IS2Container#GetComponent(object componentKey) is either a System.Type which represents component type declaration or a component name. Refer to component tag for further information. Component class where instanceof class is true may be gotten from the container. The class, however, should be associated with an unique component in the S2Container. If there are several components of the class, TooManyRegistrationRuntimeException is raised because S2Container can not determine which component to get. Similarly, component name should be unique in the S2Container. Specifying non-unique component name will raise a TooManyRegistrationRuntimeException. Example: Following is an example to get a component by specifying a class:
    IS2Container container = S2ContainerFactory.Create(PATH);
    Hoge hoge = (Hoge) container.GetComponent(typeof(Hoge));
Example: Following code acquires a component by specifying a compnent name:
    IS2Container container = S2ContainerFactory.Create(PATH);
    Hoge hoge = (Hoge) container.GetComponent("hoge");
### Application Configuration File <s2.net> section may be added to the application configuration file (not a dicon file). <s2.net> session specifies root configuration file (dicon file) and assembly to load when S2Container is created. Specified configuration file is set to the root element when S2.NET.Framework.Container.Factory.SingletonS2ContainerFactory#Init in invoked. Specified assembly is read in to an application domain when S2.NET.Framework.Container.Factory.S2ContainerFactory#Create is invoked.
    <configuration>
       <configSections>
          <section name="s2.net"
             type="S2.NET.Framework.Xml.S2SectionHandler, s2dotnet" />
       </configSections>

       <s2.net>
          <!-- SingletonS2ContainerFactory#Init sets specified dicon file
              as the initial dicon file -->
          <configPath>App.dicon</configPath>

          <!-- Set assemblies specified when creating an S2Container
               into AppDomain (S2ContainerFactory#Create) -->
          <assemblys>
             <assembly>Assembly name1</assembly>
             <assembly>Assembly name2</assembly>
          </assemblys>
       </s2.net>

    </configuration>
### Dependency Injection Types There are three types of Dependency Injection: (1) Constructor injection which sets component constructs by means of a constructor argument, (2) Property injection which sets using set accessor of a property (3) Method injection which sets using an initialize method. Method injection is a dependency injection introduced by S2. s2dotnet supports all three types of dependecy injection as well as their hybrid. ### Constructor Injection Constructor injection applies dependency injection to an arbitrary argument in a constructor. Following items are entered in the S2Container configuration file: Component specification Component is specified by a component tag. class attribute is used to specify a class name. name attribute is used to specify a component name. Constructor arguments Arguments to be passed to a component constructor is specified as values to arg tags. When the value is a string, it is surrounded by double quotations (".
    <components>
        <component name="..." class="...">

              <arg>...</arg>
        </component>
    </components>
Refer to Construtor Injection for an example. ### Property Injection Property injection uses set accessor of a property. Following items are specified in the S2Container configuration file: Component Specification Component specification is similar to constructor injection. name attribute may be used to assign a name to a component. Setting a property Component property is specified by a property tag that is a child of the component tag. Property name is specified by a name attribute.
    <components>
        <component name="..." class="...">
              <property name="...">...</property>

        </component>
    </components>
Refer to Property Injection for detailed information. ### Method Injection Method injection invokes a method and applieds dependency injection. Following items are specified in the S2Container configuration file. Component specification Component specification is the same as constructor injection. Component may be assigned a name by using name attribute. Specify initialization method. Method in a component is invoked by specifying initMethod tag. name attribute is used to specify the name of the method to invoke. Arguments to the method are specified in the arg child tags. name attribute may be omitted and JScript.NET may be used instead. In this situtation, the component itself is specified by self.
    <components>
        <component name="..." class="...">
              <initMethod>...</initMethod>

        </component>
    </components>
Refer to Method Injection for an example. ### Dividing and Including S2Container Configuration Files If all configuration are written in a single file, the file soon becomes very large. S2Container allows developers to divide the configuration file into several files and supports include clause to logically construct one configuration file from these files. Following is an example of including content of bar.dicon file:
    <components>
        <include path="bar.dicon"/>
    </components>
File to include is specified in the path attribute of a include tag. Refer to include tag for detailed information. Component are searched in the following order: (1) In the component where the component is registered (2) In child S2Container in order of the include statement. In the following components definition, "Foo" is searched first, followed by "aaa.dicon" and lastly by "bbb".
    <components>
        <include path="aaa.dicon"/>
        <include path="bbb.dicon"/>
        <component class="Examples.Container.Foo" />

    </components>
When automatically using constructor injection and setter injection, it is possible to automatically inject components in configuration to be included. Refer to automatic binding for conditions to automatically inject dependencies. Following is an example to show the order of component search. Property of a component to set by setter injection (HelloImpl) is defined in both included configuration files aaa.dicon and bbb.dicon. Let's find out which component HelloClient will use. ##### root.dicon
    <components>
        <include path="S2/NET/Examples/Reference/Includes/aaa.dicon"/>
        <include path="S2/NET/Examples/Reference/Includes/bbb.dicon"/>

        <component name="root" class="S2.NET.Examples.Reference.Includes.Impl.HelloClientImpl"/>

    </components>
##### aaa.dicon
    <components>
        <component class="S2.NET.Examples.Reference.Includes.Impl.HelloImpl">
            <property name="Message">"Hello Aaa!"</property>

        </component>

        <component name="aaa" class="S2.NET.Examples.Reference.Includes.Impl.HelloClientImpl"/>
    </components>
##### bbb.dicon
    <components>
        <component class="S2.NET.Examples.Reference.Includes.Impl.HelloImpl">
            <property name="Message">"Hello Bbb!"</property>
        </component>

        <component name="bbb" class="S2.NET.Examples.Reference.Includes.HelloClientImpl"/>
    </components>
Content of each component is as follows:
    namespace S2.NET.Examples.Reference.Includes
    {
        public interface IHelloClient
        {
            void ShowMessage();
        }
    }
    namespace S2.NET.Examples.Reference.Includes.Impl
    {
        public class HelloClientImpl : IHelloClient
        {
            private IHello hello;

            public HelloClientImpl() {}

            public IHello Hello
            {
                get { return this.hello; }
                set { this.hello = value; }
            }

            public void ShowMessage()
            {
                Console.WriteLine(this.Hello.Message);
            }
        }
    }
    namespace S2.NET.Examples.Reference.Includes
    {
        public interface IHello
        {
            string Message
            {
                set;
                get;
            }
        }
    }
    namespace S2.NET.Examples.Reference.Includes.Impl
    {
        public class HelloImpl : IHello
        {
            private string helloMessage;

            public HelloImpl() {}

            public string Message
            {
                get { return this.helloMessage; }
                set { this.helloMessage = value; }
            }
        }
    }
HelloImpl only defines Message property. Following are result of invoking showMessage() method in each HelloClient. ##### Result of RootHelloClient
    Hello Aaa!
S2Container will first try to find HelloImpl in root.dicon. Since HelloImpl is not defined in root.dicon, S2Container will next try to find it in the first included file, aaa.dicon. Since HelloImpl is defined in aaa.dicon, this definition is used and "Hello Aaa!" is outputted. ##### Result of aaa
    Hello Aaa!
aaa used a component defined in aaa.dicon.When injection is automatically done, child S2Container is unable to use component defined in the parent S2Container. For example, even if HelloImpl is defined in root.dicon, it will not be automatically injected into aaa. ##### Result of bbb
    Hello Bbb!
Similar to the case with aaa, bbb uses HelloImpl component defined in bbb.dicon. Files in this example are available in the S2/NET/Examples/Reference/Includes in S2.NET.Examples project. ### Namespace Namespace is used to distinguish component definitions from several configuration file. Namespace is specified by namespace attribute of a components tag. ##### foo.dicon
    <components namespace="Foo">
        <component name="aaa" .../>

        <component name="bbb" ...>
            <arg>aaa</arg>
        </component>
    </components>
##### bar.dicon
    <components namespace="Bar">
        <include path="foo.dicon"/>
        <component name="aaa" .../>

        <component name="bbb" ...>
            <arg>aaa</arg>
        </component>
        <component name="ccc" ...>

            <arg>foo.aaa</arg>
        </component>
    </components>
##### app.dicon
    <components>
        <include path="bar.dicon"/>
    </components>
Namespace is not necessary to require to reference components in the same S2Container. To reference components in other S2Container, however, namespace prefix associated with the S2Container is prepended to the component name. For example, foo.aaa and bar.aaa have the same component name "aaa" but have different namespace prefix. Thus, they are treated as two different components. It is a convention to name the configuration file namespace.dicon. ### Instance Management instance attribute of a component tag specifies how component instance is managed by a S2Container. Default is singleton which implies IS2Containter.GetComponent() method always gets the same component. To get a new component each time IS2Container.getComponent() method is invoked, set the instance attribute to prototype. To manage component based on request (System.Web.HttpRequest), set the instance attribute to request. To manage based on a session, set the instance attribute to session. When using Seasar framework with a presentation framework, there may sometimes be a need to set an instance created by a presentation framework to a component managed by S2Container. In this kind of circumstances where Dependency Injection to a component outside the S2Container is necessary, the following method are used. - S2.NET.Framework.Container.IS2Container#InjectDependency(Object outerComponent) - S2.NET.Framework.Container.IS2Container#InjectDependency(Object outerComponent, Type componentType) - S2.NET.Framework.Container.IS2Container#InjectDependency(Object outerComponent, string componentName) Specify external component in the first argument and external component class or component name in the second argument. Also, set instance attribute to outer in S2Container definition.
instance attribute | Description
--- | ---
singleton (default) | Same instance is returned on every invocation of IS2Container.GetComponent().
prototype | New instance is returned on each invocation of IS2Container.GetComponent().
request | One instance is created for each request. A component is saved to a request using the name set to the name attribute. S2HttpModule must be set when using request.
session | One instance is created for each session. A component is saved to a session using the name set to the name attribute. S2HttpModule must be set when using session.
outer | Instance of a component is created outside of S2Container. Only dependency is injected. Aspect and Constructor injection can not be applied.
### Lifecycleル Using initMethod and destroyMethod, component lifecycle may also be managed by a container. Method specified by initMethod tag is invoked when S2Container is initialized (S2Container.Init()) and method specified by destroyMethod tag is invoked when S2Container is destroyed (S2Container.Destroy()). initMethod is executed in order as they are defined in the container configuration and destroyMethod is executed in reverse order as they are defined in the container configuration. When instance attribute is not "singleton", destroyMethod is ignored. Following is an example to set aaa to 111 on initialization and set aa to null termination to System.Collections.Hashtable#Add() method.
    <components namespace="bar">

        <component name="table" class="System.Collections.Hashtable">
            <initMethod name="Add">
                <arg>"aaa"</arg>
                <arg>111</arg>
            </initMethod>
            <destroyMethod name="Add">
                <arg>"aaa"</arg>
                <arg>null</arg>
            </destroyMethod>
        </component>
    </components>
### Automatic Binding By default, dependency between container is automatically resolved when type is an interface. It is also possible to specify autoBinding attribute in a component tag.
autoBinding | Description
--- | ---
auto(default) | Is an argument is not specified and type is an interface,it is automatically bound. Default values are set to arguments whose type is not an interface. If default value is not available, an argument is set to null. If a property is explicitly specified, it is used. If property is not specified and property type is an interface, it is automatically bound.
constructor | If an argument to a constructor is explicitly specified, that argument is used. Is an argument is not specified and type is an interface,it is automatically bound. Default values are set to arguments whose type is not an interface. If default value is not available, an argument is set to null. If a property is explicitly specified, it is used.
property | If an argument to a constructor is explicitly specified, that argument is used. If there is no specification, default constructor is used. Type interface property is automatically bound.
none | If an argument to a constructor is explicitly specified, that argument is used. If a property is explicitly specified, it is used.
Refer to automatic binding (constructor injection) and automatic binding (property injection) for examples. ### Using S2Container from a component Component should not depend on a S2Container but there are some situations where a component may need to invoke S2Container method. S2Container is defined with a name "container" so is the value of arg or property tag is set to "container" it is possible to get an instance of a container. Furthermore, it is also possible to automatically bind by defining a S2Container type setter method. Following are examples of using arg and property tag to specify "container".
    <components>
        <component class="Examples.Dicon.BarImpl">
            <arg>container</arg>
        </component>

        <component class="Examples.Dicon.FooImpl">
            <property name="Foo">container</property>
        </component>
    </components>
### S2HttpModule When using .NET Framework from an application, S2Container is explictly created. However, when S2Container is required from an web application, following class is used to create a S2Container: - S2.NET.Framework.Container.Web.S2HttpModule To use S2HttpModule, following items may be enteredin the Web.config file. Sample Web.config file is available in S2.NET/Framework/Container/Web/Web.config.
        <httpModules>
    	 <add name="S2HttpModule"
    	     type="S2.NET.Framework.Container.Web.S2HttpModule, s2dotnet" />
        </httpModules>
Path of root S2Container configuration is specified in the configPath element in s2.net section in the Application Configuration File. After starting S2HttpModule, S2Container instance may be acquired by the following method: - S2.NET.Framework.Container.Factory.SingletonS2ContainerFactory#GetContainer() When using S2HttpModule, HttpApplication may be accessed as a component named httpApplication. ### Role of app.dicon As a convention, root S2Container file is named app.dicon. It is also a convention to not define any component in app.dicon file. Resources that uses the default namespace is entered in this file.
    <components>

        <include path="Examples/foo.dicon"/>
        <include path="Examples/bar.dicon"/>
             <!-- include all second level configuration file -->
    </components>
### Applying AOP AOP may be applied to a component. Following is an example of applying TraceInterceptor to a Date class. The current s2dot.net restricts usage of AOP to class extending System.MarshalByRefObject or an interface receiving a component. Following is an example to apply TraceInterceptor to an ArrayList:
    <components>
        <component name="traceInterceptor"
                   class="S2.NET.Framework.Aop.Interceptors.TraceInterceptor"/>

        <component class="System.Collections.ArrayList">
            <aspect>traceInterceptor</aspect>
        </component>

        <component class="TestS2.NET.Framework.Container.Factory.AspectTagHandlerTest+FooImpl">
            <aspect pointcut="Time, GetHashCode">traceInterceptor</aspect>
        </component>

    </components>
Interceptor name is specified as a value to aspect tag. Multiple method names and property names may be specified in a pointcut attribute by delimiting with a comma. If a pointcut attribute is not specified, all methods in an interface implemented by component will be implied. Regular expression (System.Text.RegularExpressions.Regex) may be used to specify an method name. Following is an example of a configuration.
    private const string PATH = "Framework/Container/Factory/AspectTagHandlerTest.dicon";

    [Test]
    public void TestAspect()
    {
        IS2Container container = S2ContainerFactory.Create(PATH);

        IList list = (IList) container.GetComponent(typeof(IList));
        int count = list.Count;

        IFoo foo = (IFoo) container.GetComponent(typeof(IFoo));
        int time = foo.Time;
        foo.ToString();
        int hashCode = foo.GetHashCode();
    }

    public interface IFoo
    {
        int Time { get; }
        int GetHashCode();
        string ToString();
    }

    public class FooImpl : IFoo
    {
        private int time_ = 3;

        public FooImpl()
        {
        }

        #region IFoo member

        public int Time
            {
                get
                {
                    return time_;
                }
            }

            public override int GetHashCode()
            {
                return base.GetHashCode();
            }

            public override string ToString()
            {
                return time_.ToString();
            }

            #endregion
        }
Result is as follows:
    BEGIN System.Collections.ICollection#get_Count()
    END System.Collections.ICollection#get_Count() : 0
    BEGIN TestS2.NET.Framework.Container.Factory.AspectTagHandlerTest+IFoo#get_Time()
    END TestS2.NET.Framework.Container.Factory.AspectTagHandlerTest+IFoo#get_Time() : 3
    BEGIN TestS2.NET.Framework.Container.Factory.AspectTagHandlerTest+IFoo#GetHashCode()
    END TestS2.NET.Framework.Container.Factory.AspectTagHandlerTest+IFoo#GetHashCode() : 1168
### Meta data meta data may be applied to components, component, arg, and property tags. meta tag is specified as a child element to the element which is to have a meta tag. Following is an example of specifying a meta tag to a components tag.
    <components>
        <meta name="aaa">111</meta>
    </components>
Meta data information specified in components, component, arg, and property tags may be retrieved using the following methods defined in IS2Container, IComponentDef, IArgDef, and IPropertyDef. public int MetaDefSize public IMetaDef GetMetaDef(int index) public IMetaDef GetMetaDef(string name) public IMetaDef[] GetMetaDefs(string name) ### Automatic Binding of Request HttpRequest may be automatically bound to a component by defining HttpRequestRequest { set; } to a component and defining S2HttpModule in Web.config file. S2Container will automatically set the request. Likewise, HttpServletResponse and HttpSession may also be automatically bound by just defining a property (set accessory). Furthermore, by using S2HttpModule, HttpRequest, HttpResponse, HttpSessionState, and HttpApplication may respectively be accessed as a component named request, response, session, and httpApplication. ## S2Container Definition Reference ### DOCTYPE XML declaration in DOCTYPE is as follows:
    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
    "http://www.seasar.org/dtd/components21.dtd">
    <components>
        <component name="hello"
                class="S2.NET.Examples.Reference.Injection.HelloConstructorInjection">
            <arg>"Hello World!"</arg>
        </component>

        <component name="ConstructorInjection"
                class="S2.NET.Examples.Reference.Injection.HelloConstructorInjectionClient" />
    </components>
### components tag (required) Root tag #### namespace attribute (optional) Namespace may be specified.
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
    "http://www.seasar.org/dtd/components21.dtd">
    <components namespace="hoge">

        ...
    </components>
### include tag (optional) Used to include divided S2Container configuration files. #### path attribute (required) Path of configuration file may be specified. Path of a configuration file may be specified by embedded resource or by a file system. When specifying by embedded resource, complete namespace must be included using slash (/ as a separator character. Configuration build action property should be set to the embedded resource. C# project creates a namespace when a folder is created, but VB.NET does not. For example, if project folder is /Sample/Logic/aaa.dicon, C# project assignes /Sample/Logic/aaa.dicon as a default namespace, but a default name space in VB.NET is /aaa.dicon. When using a file system, absolute or relative file path is specified. Configuration file may also be specified by a combination of embedded and file system. When there is a conflict between the choice, file system specification takes precedence. It is necessary to specify before the component tag.
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
    "http://www.seasar.org/dtd/components21.dtd">

    <components>
        <include path="aaa/bbb/ccc.dicon" />
    </components>
### component tag (optional) Define a component. #### class attribute (optional) Specify full path of a class. If JScript.NET expression is used as a value of a tag to specify a component, class attribute may be omitted. If class attribute is specified when JScript.NET expression is used, it will be type checked. #### name attribute (optional) Specify name. Must be usable as a .NET id. Refer to Getting a component for further information. #### instance attribute (optional) Specify how S2Container manages instance of a component. Possible values are singleton (default), prototype, outer, request, and session. Refer to instance management for further information. #### autoBinding attribute (optional) Specify how S2Container resolves dependencies between components. Possible values are auto (default), constructor, property, and none. Refer to automatic binding for further information. ### arg tag (optional) If specified as a child tag to a component tag, will be used as arguments to a contructor. Arguments are passed to a constructor in the order they are specified. If specified as a child tag to a initMethod tag or a destroyMethod tag, will be used as arguments to a method. Arguments are passed to a constructor in the order they are specified. Value of a property is specified as a value to JScript.NET expression or in a child component tag. ### property tag (optional) Used as a child tag to a component tag. Value of a property is specified as a value to JScript.NET expression or in a child component tag. #### name attribute (required) Specify property name. ### meta tag (optional) Specified as a child tag to a components tag, component tag, arg tag, property tag. Value of a metadata is specified as a value to OGNL expression or in a child component tag. #### name attribute (optional) Specify tag name. ### initMethod tag (optional) Written as a child tag to component tag. Arguments are specified in the arg child tags. Method in a component may be invoked without specifying a name attribute by using JScript.NET expression. Only has meaning when used in self representing initMethod tag where component tag itself is defined, out representing Console.Out, err representing Console.Error. #### name attribute (optional) Specify a method name
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"

    "http://www.seasar.org/dtd/components21.dtd">
    <components>
        <component class="System.Collections.Hashtable">
            <initMethod name="Add">
                <arg>"aaa"</arg>
                <arg>111</arg>
            </initMethod>

            <initMethod>self.Add("aaa", 111)</initMethod>
            <initMethod>out.WriteLine("Hello")</initMethod>
        </component>
    </components>
### destroyMethod tag (optional) same as an initMethod tag. ### aspect tag (optional) Weave an aspect into a component. Refer to aspect tag for further information. ### description tag (optional) Description tag may be used as a child tag to components tag, component tag, arg tag, and property tag. ### JScript.NET Expression S2Container.NET uses JScript.NET as a scripting language. String expression may be converted into a .NET object. String are surrounded by double quotations (i.e. ". For example, "hoge" char are surrounded by single quoations (i.e. '. For example , 'a' Numerials are written as is. For example, 123 Boolean are written as either true, false Standard library class (mscorlib.dll) such as new DateTime() may be invoked. (Namespace System is omitted when invoking.) Refer to JScript.NET Reference for further information. ## Examples s2dotnet must be set up before trying examples in this section. S2.NET.Examples project will be created as a Windows application. The example may be executed by setting S2.NET.Examples project as a startup project and selecting the F5 key. ### Constructor injection This example will use constructor injection to display a message. Following files are created in this example: Interface (IHello.cs) Implementation class (HelloConstructorInjection.cs) dicon file (HelloConstructorInjection.dicon) Execution class (HelloconstructorInjectionClient class in HelloConstructorInjection.cs) ##### Create an interface Define ShowMessage() Interface is defined first. Developers are able to design on interfaces without knowing the actual implementation. Furthermore, a Mock may be used instead of the actual implementation during the unit test.
    namespace S2.NET.Examples.Reference.Injection
    {
        public interface IHello
        {
            void ShowMessage();
        }
    }
##### Create implementation class Define constructor with string argument Implement ShowMessage() ShowMessage() displays the message received by the constructor.
    using System;
    namespace S2.NET.Examples.Reference.Injection
    {
        public class HelloConstructorInjection : IHello
        {
            private string message;

            public HelloConstructorInjection(string message)
            {
                this.message = message;
            }

            public void ShowMessage()
            {
                Console.WriteLine(this.message);
            }
        }
    }
##### Create dicon file Define a component using a component tag Specify arguments to a constructor as values to children arg tags. The message is set to a component by S2Container. Component is constructed according to the configuration file. S2/NET/Examples/Reference/Injection/HelloConstructorInjection.dicon
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
    "http://www.seasar.org/dtd/components21.dtd">
    <components>
        <component name="hello"
                class="S2.NET.Examples.Reference.Injection.HelloConstructorInjection">
            <arg>"Hello World!"</arg>
        </component>

        <component name="ConstructorInjection"
            class="S2.NET.Examples.Reference.Injection.HelloConstructorInjectionClient" />
    </components>
##### Create execution class Create a S2Container by invoking S2ContainerFactory.Create(String path). Get a component from S2Container by invoking GetComponent(). Invoke a method in the acquired component.
    using System;

    using S2.NET.Framework.Container;
    using S2.NET.Framework.Container.Factory;

    namespace S2.NET.Examples.Reference.Injection
    {
        public class HelloConstructorInjectionClient
        {
            private static readonly String PATH =
                "S2/NET/Examples/Reference/Injection/HelloConstructorInjection.dicon";

            public void Main()
            {
                // when getting a component by specifying a type
                IS2Container container = S2ContainerFactory.Create(PATH);
                IHello hello = (IHello) container.GetComponent(typeof(IHello));
                hello.ShowMessage();

                // when getting a component by specifying a name
                IHello hello2 = (IHello) container.GetComponent("hello");
                hello2.ShowMessage();
            }
        }
    }
##### Result Value of the arg tag should be properly displayed as follows:
    Hello World!
    Hello World!
Files in this example is available in the S2/NET/Examples/Reference/Injection folder in the S2.NET.Examples project. ### Property injection This example displays a message using property injection. Following files are created in the example: Interface (IHello.cs) (same as in the constructor injection) Implementation class (HelloPropertyInjection.cs) dicon file (HelloPropertyInjection.dicon) Implementation class (HelloPropertyInjection.cs中のHelloPropertyInjectionClient class) ##### Create an interface Define ShowMessage() Interface is the same as in the constructor injection example. Definition of get assessor for a property and set assessor are not required because whether to use constructor or set assessor is a matter of implementation.
    namespace S2.NET.Examples.Reference.Injection
    {
        public interface IHello
        {
            void ShowMessage();
        }
    }
##### Create implementation class Define a property Implement ShowMessage() ShowMessage() displays a message received by property method.
    using System;

    namespace S2.NET.Examples.Reference.Injection
    {
        public class HelloPropertyInjection : IHello
        {
            private string message;

            public HelloPropertyInjection() {}

            public string Message
            {
                get { return this.message; }
                set { this.message = value; }
            }

            public void ShowMessage()
            {
                Console.WriteLine(this.message);
            }
        }
    }
##### Create dicon file Define a component using component tags Set value to a property using property tag which is a child of a component tag. S2/NET/Examples/Reference/Injection/HelloPropertyInjection.dicon
    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
    "http://www.seasar.org/dtd/components21.dtd">
    <components>
        <component class="S2.NET.Examples.Reference.Injection.HelloPropertyInjection">
            <property name="Message">"Hello World!"</property>
        </component>

        <component name="PropertyInjection"
            class="S2.NET.Examples.Reference.Injection.HelloPropertyInjectionClient" />
    </components>
##### Create execution file Create S2Container by invoking on S2ContainerFactory.Create(string path). Get a component from S2Container by invoking GetComponent(). Invoke a method in an acquired component.
    using System;

    using S2.NET.Framework.Container;
    using S2.NET.Framework.Container.Factory;

    namespace S2.NET.Examples.Reference.Injection
    {
        public class HelloPropertyInjectionClient
        {
            private static readonly String PATH =
                "S2/NET/Examples/Reference/Injection/HelloPropertyInjection.dicon";

            public void Main()
            {
                IS2Container container = S2ContainerFactory.Create(PATH);
                IHello hello = (IHello) container.GetComponent(typeof(IHello));
                hello.ShowMessage();
            }
        }
    }
##### Result String value of a property tag should be displayed as below:
    Hello World!
Files in this example are available in S2/NET/Examples/Reference/Injection folder in S2.NET.Examples project. ### Method injection This example display a message using method injection. Following files are created in this example: Interface (IHello.cs) Implementation class (HelloMethodInjection.cs) dicon file (HelloMethodInjection.dicon) Execution class (HelloMethodInjectionClient class in HelloMethodInjection.cs) ##### Create an interface Define ShowMessage() In most cases, append method is called several times but in this example, interface is the same as that defined in constructor injection.
    namespace S2.NET.Examples.Reference.Injection
    {
        public interface IHello
        {
            void ShowMessage();
        }
    }
##### Create implementation class Define AddMessage() Implement ShowMessage() AddMessage(string message) appends a message several times and ShowMessage() displays the message.
    using System;
    using System.Text;

    namespace S2.NET.Examples.Reference.Injection
    {
        public class HelloMethodInjection : IHello
        {
            private StringBuilder builder = new StringBuilder();

            public HelloMethodInjection() {}

            public void AddMessage(string message)
            {
                this.builder.Append(message);
            }

            public void ShowMessage()
            {
                Console.WriteLine(this.builder.ToString());
            }
        }
    }
##### Create dicon file Define a component using component tags Set a value to arguments of a method by specifying initMethod that is a child of a component tag. Set AddMessage(string message) to "Hello" in arg tag Specify AddMessage(string message) to "World!" using JScript.NET expression S2/NET/Examples/Reference/Injection/HelloMethodInjection.dicon
    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
    "http://www.seasar.org/dtd/components21.dtd">
    <components>
        <component class="S2.NET.Examples.Reference.Injection.HelloMethodInjection">
            <initMethod name="AddMessage">
                <arg>"Hello "</arg>
            </initMethod>
            <initMethod>self.AddMessage("World!")</initMethod>
        </component>

        <component name="MethodInjection"
            class="S2.NET.Examples.Reference.Injection.HelloMethodInjectionClient" />
    </components>
##### Create execution class Create S2Container by invoking S2ContainerFactory.Create(string path) Get a component from the S2Container by invoking GetComponent() Invoke a method in acquired component
    using System;

    using S2.NET.Framework.Container;
    using S2.NET.Framework.Container.Factory;

    namespace S2.NET.Examples.Reference.Injection
    {
        public class HelloMethodInjectionClient
        {
            private static readonly String PATH =
                "S2/NET/Examples/Reference/Injection/HelloMethodInjection.dicon";

            public void Main()
            {
                IS2Container container = S2ContainerFactory.Create(PATH);
                IHello hello = (IHello) container.GetComponent(typeof(IHello));
                hello.ShowMessage();
            }
        }
    }
##### Result Value set in initMethod tag should be displayed as below:
    Hello World!
Files in this example are available in S2/NET/Examples/Reference/Injection folder in S2.NET.Examples project. ### Automatic binding (constructor injection) Display a message using automatic binding. Following files are created in this example: Interface (IHello.cs) Class implementing an interface (AutoHelloConstructorInjection.cs) dicon file(AutoHelloConstructorInjection.dicon) Execution class(AutoHelloConstructorInjectionClient class in AutoHelloConstructorInjection.cs) ##### Create an interface Define ShowMessage()
    namespace S2.NET.Examples.Reference.AutoBinding
    {
        public interface IHello
        {
            void ShowMessage();
        }
    }
##### Create execution class Define a constructor with IDictionary as an argument Implement ShowMessage() Constructor receives IDictionary and ShowMesssage() searches IDictionary with key "hello" and displays the result.
    using System;
    using System.Collections;

    namespace S2.NET.Examples.Reference.AutoBinding
    {
        public class AutoHelloConstructorInjection : IHello
        {
            private IDictionary dictionary;

            public AutoHelloConstructorInjection(IDictionary dictionary)
            {
                this.dictionary = dictionary;
            }

            public void ShowMessage()
            {
                Console.WriteLine(dictionary["hello"]);
            }
        }
    }
##### Create dicon file Define System.Collections.Hashtable, which is an implementation of System.Collections.IDictionary, as a component using component tags. In initMethod that is a child tag to a component tag, set Hashtable key to "hello" and value to "Hello World!" Define AutoHelloConstructorInjection as a component using component tags. In this example, "auto" is explicitly specified but since this is the default autoBinding attribute value, it is usually not explicitly specified. Note that AutoHelloConstructorInjection does not have a arg tag. When using constructor injection, it is normally necessary to define arguments using arg tags but when implementation class of IDictionary is defined in S2Container, S2Container will search within itself and automatically set the arguments. However, if the property type is not an interface, automatic binding does not occur. S2/NET/Examples/Reference/AutoBinding/AutoHelloConstructorInjection.dicon
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
    "http://www.seasar.org/dtd/components21.dtd">
    <components>

        <component class="System.Collections.Hashtable">
            <initMethod name="Add">
                <arg>"hello"</arg>
                <arg>"Hello World!"</arg>
            </initMethod>
        </component>

        <component name="hello" autoBinding="auto"
          class="S2.NET.Examples.Reference.AutoBinding.AutoHelloConstructorInjection" />

        <component name="AutoConstructorInjection"
          class="S2.NET.Examples.Reference.AutoBinding.AutoHelloConstructorInjectionClient" />

    </components>
##### Create execution class Create S2Container by invoking S2ContainerFactory.Create(string path)。 Get component from S2Container by invoking GetComponent() Invoke method in an acquired component
    using System;
    using S2.NET.Framework.Container;
    using S2.NET.Framework.Container.Factory;
    namespace S2.NET.Examples.Reference.AutoBinding
    {
        public class AutoHelloConstructorInjectionClient
        {
            private static readonly String PATH =
                "S2/NET/Examples/Reference/AutoBinding/AutoHelloConstructorInjection.dicon";

            public void Main()
            {
                IS2Container container = S2ContainerFactory.Create(PATH);
                IHello hello = (IHello) container.GetComponent(typeof(IHello));
                hello.ShowMessage();
            }
        }
    }
##### Result Value set to the Hashtable should be displayed indicating argument to the constructor was automatically set.
    Hello World!
Files in this example are available in S2/NET/Examples/Reference/AutoBinding folder in the S2.NET.Examples project. ### Automatic binding (property injection) This example displays a message using automatic binding. Following files are created in this example: Interface (IHello.cs) Class implementing an interface (AutoHelloPropertyInjection.cs) dicon file (AutoHelloPropertyInjection.dicon) Execution class (AutoHelloPropertyInjection.cs中のAutoHelloPropertyInjectionClient class) ##### Create interface Implement ShowMessage()
    namespace S2.NET.Examples.Reference.AutoBinding
    {
        public interface IHello
        {
            void ShowMessage();
        }
    }
##### Create execution class Define property of type IDictionary Implement ShowMessage() Set assessor in IDictionary Message receives IDictionary and ShowMessage() uses key value "hello" to get and display a string from IDictionary.
    using System;
    using System.Collections;

    namespace S2.NET.Examples.Reference.AutoBinding
    {
        public class AutoHelloPropertyInjection : IHello
        {
            private IDictionary dictionary;

            public AutoHelloPropertyInjection()
            {
            }

            public IDictionary Message
            {
                set { dictionary = value; }
            }

            public void ShowMessage()
            {
                Console.WriteLine(dictionary["hello"]);
            }
        }
    }
##### Create dicon file Define System.Collections.Hashtable, which is an implement clas of System.Collections.IDictionary, as a component using component tags. In initMethod that is a child tag to a component tag, set Hashtable key to "hello" and value to "Hello World!" Define AutoHelloPropertyInjection as a component using component tags. In this example, "auto" is explicitly specified but since this is the default autoBinding attribute value, it is usually not explicitly specified. Note that AutoHelloPropertyInjection does not have a property tag. When using property injection, it is normally necessary to define a property using property tags but when implementation class of IDictionary is defined in S2Container, S2Container will search within itself and automatically set the property. However, if the property type is not an interface, automatic binding does not occur. S2/NET/Examples/Reference/AutoBinding/AutoHelloPropertyInjection.dicon
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
    "http://www.seasar.org/dtd/components21.dtd">
    <components>

        <component class="System.Collections.Hashtable">
            <initMethod name="Add">
                <arg>"hello"</arg>
                <arg>"Hello World!"</arg>
            </initMethod>
        </component>

        <component name="hello" autoBinding="auto"
          class="S2.NET.Examples.Reference.AutoBinding.AutoHelloPropertyInjection" />

        <component name="AutoPropertyInjection"
          class="S2.NET.Examples.Reference.AutoBinding.AutoHelloPropertyInjectionClient" />

    </components>
##### Create execution class Create S2Container by invoking S2ContainerFactory.Create(string path)。 Get a component from S2Container using GetComponent() Invoke method in the acquired component.
    using System;
    using S2.NET.Framework.Container;
    using S2.NET.Framework.Container.Factory;
    namespace S2.NET.Examples.Reference.AutoBinding
    {
        public class AutoHelloPropertyInjectionClient
        {
            private static readonly String PATH =
                "S2/NET/Examples/Reference/AutoBinding/AutoHelloPropertyInjection.dicon";

            public void Main()
            {
                IS2Container container = S2ContainerFactory.Create(PATH);
                IHello hello = (IHello) container.GetComponent(typeof(IHello));
                hello.ShowMessage();
            }
        }
    }
##### Result Value set to he Hashtable should be displayed indicating the property was automatically set.
    Hello World!
Files in this example are available in the S2/NET/Examples/Reference/AutoBinding folder in S2.NET.Examples project. |
Trans. by H.Ozawa | Copyright© 2004-2007, The Seasar Foundation and the others. All rights reserved.