Unity Configuration
Artifacts referenced in the JSL (using ref
attribute) must be registered in a Unity container using UnityLoader
class. It has two protected methods that can be overridden: LoadConfiguration
(IUnityContainer
), which makes registrations for the base configuration of the batch, and LoadArtifacts
(IUnityContainer
), which registers the artifacts of the job (e.g., readers, writers).
Batch Configuration¶
The implementation of LoadConfiguration
in UnityLoader
does required registrations by default, thus it is not required to override it unless this default configuration is needed to be modified for the current batch.
The only mandatory interface to register is IJobOperator
, but default implementation, SimpleJobOperator
does require registrations of interfaces IJobExplorer
, IJobRepository
, IJobLauncher
, and IListableJobLocator
. If using splits or partitioned steps, it is also required to register a task executor (ITaskExecutor
).
Job Operator¶
The job operator offers a basic interface to manage job executions (e.g., starting, restarting jobs). It is recommended to use the default implementation, SimpleJobOperator
, but users are free to provide their own implementation.
Job Explorer and Job Repository¶
The job explorer manages the persistence of batch entities while job repository holds all associated meta-information. Both can either be persisted in a database or stored in memory. Database persistence is required to restart a job but in-memory explorer and repository are useful during development.
For the job repository to be persisted in a database, an ad hoc list of tables must be created in a database schema. Creation (and drop) SQL scripts are being provided for the three supported RDBMS (MS SQL Server, Oracle database and IBM DB2), for details please refer to corresponding appendix section:
When using the default implementation of UnityLoader.LoadConfiguration
, one can override PersistenceSupport
property to choose whether to use database or memory explorer and repository. By default, property returns false
.
Example 4.13. Setting Database Persistence of Job Explorer and Job Repository¶
protected override bool PersistenceSupport { get { return true; } }
ConnectionStringSettings
with the name “Default” must be registered in the Unity container.
Job Launcher¶
The job launcher is responsible for launching a job. By default, UnityLoader
uses an instance of SimpleJobLauncher
with an instance of SyncTaskExecutor
as a task executor.
Job Locator¶
The job locator, which implements IListableJobLocator
, is used to retrieve a job configuration from its name. If it also implements IJobRegistry
, UnityLoader
will register in it all jobs that have been registered in Unity container. By default an instance of MapJobRegistry
is used.
Task Executor¶
The task executor determines how splits and partitioned steps are executed. Default implementation registered by UnityLoader
, SimpleAsyncTaskExecutor
, executes tasks in parallel. Summer Batch also provides SyncTaskExecutor
which executes tasks synchronously, in sequence.
To have a fine grained control over task execution; users can define their own task executor. A task executor must implement ITaskExecutor
interface. It has one method, void Execute(Task)
, which is responsible for executing the task passed as a parameter. It is not required that the task finishes before Execute
returns, thus multiple tasks can be executed at the same time.
Batch Artifacts¶
UnityLoader.LoadArtifacts
method is responsible for registering all the artifacts required for the job in the unity container. In particular these artifacts must be registered: readers, processors, writers, tasklets, job listeners, and step listeners.
Readers
Readers must implement IItemReader<T> interface
. "T Read()"
method returns the next read items or null
if there are more items.Type of returned items T
, must be a reference type.
Processors
Processors must implement IItemProcessor<TIn, TOut>
interface. "TOut
Process(TIn)"
method transforms the item returned by reader (of type TIn
) to an item of type TOut
for the writer. If current item must be skipped, then processor should return null
. Type of returned items TOut
, must be a reference type.
Writers
Writers must implement IItemWriter<T>
interface. "void Write(IList<T>)"
method writes the items returned by processor or reader (if there are no processor).
Takslets
Takslets must implement ITasklet
interface. "RepeatStatus Execute
(StepContribution,
ChunkContext)"
method must implement a batchlet step and is repeatedly executed until it returns RepeatStatus.Finished
.
Job listeners
Job listeners must implement IJobExecutionListener
interface. "void BeforeJob
(JobExecution)"
method is called before the job starts and "void AfterJob
(JobExecution)"
method is called after the job ends.
Step listeners
Step listeners must implement IStepExecutionListener
interface. "void BeforeStep
(StepExecution)"
method is called before the step starts and the "ExitStatus
AfterStep(StepExecution)"
method is called after the step ends. AfterStep
method return an exit status that can be used for conditional step control flow in the XML configuration (see section Batch Control Flow)
Scopes¶
Batch artifacts can be defined in two different scopes: singleton scope and step scope. A scope determines the lifetime of an instance during the execution of batch and is critical when executing steps in parallel or when sharing artifacts between different steps.
Singleton Scope¶
Artifacts defined in the singleton scope use Microsoft.Practices.Unity.ContainerControlledLifetimeManager
lifetime manager, which means that only one instance will be created during the whole job execution.
The singleton scope is the default scope. When a resolution is made and no lifetime manager has been defined, ContainerControlledLifetimeManager
lifetime manager is used.
Step Scope¶
Artifacts defined in step scope use Summer.Batch.Core.Unity.StepScope.StepScopeLifetimeManager
lifetime manager. One instance will be created for each step execution where the artifact is used. It means that if a step is executed several times (e.g., with a partitioner), the artifacts defined in step scope (like the reader or the writer) will not be shared by different executions.
Note
When an artifact in singleton scope references an artifact in step scope, a proxy is created. When proxy is used it will retrieve appropriate instance of the artifact, depending on the current step execution. Proxy creation is only possible with interfaces, which means that the reference in the singleton scope artifact must use an interface.
Additions to Unity¶
To add new features and simplify the syntax, several additions to Unity have been made.
Scope extensions¶
Two Unity extensions are used to manage scopes (see section Scopes), Summer.Batch.Core.Unity.Singleton.SingletonExtension
and Summer.Batch.Core.Unity.StepScope.StepScopeExtension
. Both are automatically added to Unity container by UnityLoader.SingletonExtension
ensures that the default lifetime manager is ContainerControlledLifetimeManager
instead of PerResolveLifetimeManager.StepScopeExtension
manages references between non step scope artifacts and step scope artifacts, as described in section Step Scope.
Initialization callback¶
A third extension is added to the container by UnityLoader: Summer.Batch.Core.Unity.PostprocessingUnityExtension
. It is used to execute a callback method once an instance of a class has been initialized. If an instance created by Unity container implements Summer.Batch.Common.Factory.IInitializationPostOperations
interface, AfterPropertiesSet
method will be called after the initialization is completed and successful. This is used to ensure an artifact is correctly configured (e.g., to make sure a reader has been given a resource to read).
New Injection Parameter Values¶
Unity uses injection parameter values to compute at resolve time value that are injected. Four new types of injection parameter values have been introduced.
Summer.Batch.Core.Unity.Injection.JobContextValue<T>
Injects a value from job context. The constructor takes key of the job context value to get as parameter. It value is not of type T
, it converts the value using its string representation.
Summer.Batch.Core.Unity.Injection.StepContextValue<T>
Injects a value from step context. The constructor takes the key of step context value to get as parameter. If value is not of type T
, it converts the value using its string representation.
Summer.Batch.Core.Unity.Injection.LateBindingInjectionValue<T>
Injects a value computed from a string given as a constructor parameter. First it computes a string value from the original string parameter by replacing any late binding sequence (i.e., “#{…}”) by a value computed at resolve time. Then the string value is converted into required type.
The late binding injection parameter value currently supports three sources for late binding sequence: (1) jobExecutionContext
, which injects a value from job context using JobContextValue
, (2) stepExecutionContext
, which injects a value from step context using StepContextValue
, and (3) settings
, which injects a string value read from application settings, in "App.config"
. For each source, a string key must be provided using the following syntax: #{source['key']
}.
For instance, the string "#{jobExecutionContext['output']}\result.txt"
with "C:\output"
as the job context value for "output"
would be replaced by "C:\output\result.txt"
.
Summer.Batch.Core.Unity.Injection.ResourceInjectionValue
Injects a resource. Resources represent files that can be read or written and are used by the readers and writers in Summer Batch. This injection parameter value takes a string and converts it to a file system resource that is injected. This string can contain late binding and is resolved using LateBindingInjectionValue
.
The constructor takes a Boolean optional parameter, many
. If many
is true, a list or resources will be returned instead of a single resource. There are two ways to specify several resources in input string: (1) separating different paths with “ ; ”, and (2) using ant-style paths with “ ? ”, “ * ”, and “ ** ” wildcards.
New Registration Syntax¶
The Summer.Batch.Core.Unity.Registration<TFrom, TTo>
class simplifies use of injection members and injection parameter values. An instance of Registration
represents a registration of a type to a Unity container. Several methods allows configuration of registration, and Register()
method performs actual registration.
There are two ways to create an instance of Registration
: to use a constructor or to use one of the extension methods for Unity containers (defined in Summer.Batch.Core.Unity.RegistrationExtension). For instance in Example 4.14, “Creating a New Registration”, registration1
and registration2
are equivalent and registration3
and registration4
are equivalent.
Example 4.14. Creating a New Registration¶
var registration1 = new Registration<IInterface, ConcreteClass>(
new ContainerControlledLifetimeManager(), container);
var registration2 = container.SingletonRegistration<IInterface, ConcreteClass>();
var registration3 = new Registration<ConcreteClass, ConcreteClass>(
"name", new StepScopeLifetimeManager(), container);
var registration4 = container.StepScopeRegistration<ConcreteClass>("name");
Configuring a Registration¶
The Registration
class has several methods to configure a registration, which all return current registration to allow chained calls. These configuration methods are separated in two types: injection member methods and injection parameter value methods. Injection member methods specify a type of injection (e.g., constructor injection) and injection parameter value methods specify a value to inject. When an injection parameter value method is called, the corresponding parameter value is added to injection member specified by the last injection member method called. In Example 4.15, “Registration of a List of Character Strings” a list of character strings is registered using the Constructor
injection member method and the Value
injection parameter value method.
Example 4.15. Registration of a List of Character Strings¶
container.SingletonRegistration<IList<string>, List<string>>("names")
.Constructor().Value(new []{ "name1", "name2" })
.Register();
Injection Member Methods¶
Constructor()
Specifies constructor injection. All of the following injection parameter values will be used as parameter for constructor. The actual constructor is inferred from parameter values at resolve time. There can only be one constructor injection per registration.
Method(string)
Specifies method injection. This parameter is the name of the method to call and all of the following injection parameter values will be used as parameter for the method. Actual method is inferred from the name and parameter values at resolve time. There may be several method injections per registration (even for the same method).
Property(string)
Specifies property injection. This parameter is the name of property to set and the following injection parameter value is the set value. There may be several property injections per registration.
Injection Parameter Value Methods¶
Instance(object)
or Value(object)
Injects the object passed as parameter. Both methods are identical and the distinction is merely semantical (Instance
for reference types and Value
for value types).
Reference<T>(string)
Injects an object that is resolved from Unity container at resolve time. Injected object is resolved using "type" passed as generic parameter and "name" passed as parameter. The name is optional. Since resolution of injected object is done at resolve time, it does not need to already be registered.
References<T>(params Type[])
Injects an array of objects that are resolved from unity container at resolve time. The objects are resolved using types passed as parameter.
References<T>(params string[])
Injects an array of objects that are resolved from unity container at resolve time. The objects are resolved using type passed as generic parameter and names passed as parameter.
References<T>(params Reference[])
Injects an array of objects that are resolved from unity container at resolve time. The objects are resolved using Reference
instances passed as parameter. The structure Summer.Batch.Core.Unity.Reference
contains a type (Type
property) and a name (Name
property).
LateBinding<T>(string)
Injects an object using the late binding injection parameter value, LateBindingInjectionValue<T>
. See section New Injection Parameter Values for more information on late binding.
Resource<T>(string)
Injects a resource using the resource injection parameter value, ResourceInjectionValue
. See section New Injection Parameter Values for more information on resource injection.
Resources<T>(string)
Injects a list of resources using the resource injection parameter value, ResourceInjectionValue
. See section New Injection Parameter Values for more information on resource injection.