Comprehensive Spring4D Manual

Spring4D is a framework for Delphi that enhances productivity by providing modern programming features such as Dependency Injection, Object Mapping, Collections, and more.

1. Dependency Injection and IoC with TContainer

Overview

Dependency Injection (DI) allows decoupling of object creation and usage, improving testability and maintainability.

Registering and Resolving Dependencies

var
  Container: TContainer;
begin
  Container := TContainer.Create;

  // Register a type
  Container.RegisterType<IMyInterface, TMyImplementation>.AsSingleton;

  // Resolve the type
  var MyInterface := Container.Resolve<IMyInterface>;
end;

Lifetime Management

Control the lifetime of objects:

Constructor Injection

Automatically inject dependencies via constructors:

TMyImplementation = class(TInterfacedObject, IMyInterface)
public
  constructor Create(Dependency: IOtherInterface);
end;

Container.RegisterType<IMyInterface, TMyImplementation>;
Container.RegisterType<IOtherInterface, TOtherImplementation>;

Property Injection

TMyImplementation = class(TInterfacedObject, IMyInterface)
public
  [Inject]
  Dependency: IOtherInterface;
end;

Container.Build;

2. Object Mapping with TMapper

Spring4D's TMapper simplifies the process of copying data between objects.

Automatic Mapping

TMapper.RegisterType<ISource, TDestination>;
var Destination: TDestination := TMapper.Map<TDestination>(Source);

Custom Mapping

TMapper.RegisterMap<ISource, TDestination>(
  procedure(const Source: ISource; var Destination: TDestination)
  begin
    Destination.Name := Source.Name.ToUpper;
  end
);

Nested Object Mapping

TMapper.RegisterType<INestedSource, TNestedDestination>;
TMapper.RegisterType<ISource, TDestination>;

Converters

Register converters for custom type transformations:

TMapper.RegisterConverter<TDateTime, string>(
  function(const Source: TDateTime): string
  begin
    Result := DateTimeToStr(Source);
  end
);

3. Collections

Spring4D includes powerful generic collections.

Lists

var
  List: IList<Integer>;
begin
  List := TCollections.CreateList<Integer>;
  List.Add(1);
  List.Add(2);
end;

Dictionaries

var
  Dict: IDictionary<Integer, string>;
begin
  Dict := TCollections.CreateDictionary<Integer, string>;
  Dict.Add(1, 'One');
end;

Thread-Safe Collections

var
  ThreadSafeList: IList<Integer>;
begin
  ThreadSafeList := TCollections.CreateThreadSafeList<Integer>;
end;

4. Functional Programming Constructs

Predicates and Anonymous Functions

var
  List: IList<Integer>;
  FilteredList: IEnumerable<Integer>;
begin
  List := TCollections.CreateList<Integer>;
  List.AddRange([1, 2, 3, 4]);
  FilteredList := List.Where(function(Value: Integer): Boolean
    begin
      Result := Value > 2;
    end);
end;

Aggregates

var
  Sum: Integer;
begin
  Sum := List.Aggregate(0, function(A, B: Integer): Integer
    begin
      Result := A + B;
    end);
end;

5. Lazy Initialization

Delays object creation until accessed.

var
  LazyValue: Lazy<Integer>;
begin
  LazyValue := Lazy<Integer>.Create(
    function: Integer begin Result := ComputeExpensiveValue; end);
end;

6. Events and Multicast Delegates

Creating and Using Events

var
  Event: IEvent<TNotifyEvent>;
begin
  Event := TEvent<TNotifyEvent>.Create;
  Event.Add(SomeProcedure);
  Event.Invoke(Sender);
end;

7. Design Patterns Support

Singleton

Container.RegisterType<TMySingleton>.AsSingleton;

Factory

Container.RegisterType<IMyInterface>(function: IMyInterface
  begin
    Result := TMyImplementation.Create;
  end);

8. Unit Testing with Mocks

Spring4D supports mock objects for testing:

var
  Mock: Mock<IMyInterface>;
begin
  Mock := TMock<IMyInterface>.Create;
  Mock.Setup.WillReturn('Value').When.SomeMethod;
end;

Best Practices

  1. Always Code to Interfaces: Reduces coupling and increases testability.
  2. Use Dependency Injection for Configurable Services.
  3. Leverage Object Mapping for API Data Transfers.
  4. Use Lazy Initialization for Expensive Computations.

Additional Resources

Explore more in the Spring4D GitHub Repository.