A simple Dependency Injection Container for Delphi

Delphi 2010, Delphi Dependency Injection, Design Patterns 10 Comments »

As wikipedia says:

“Dependency injection (DI) in computer programming refers to the process of supplying an external dependency to a software component. It is a specific form of inversion of control where the concern being inverted is the process of obtaining the needed dependency. The term was first coined by Martin Fowler to describe the mechanism more clearly.

Many of us have already read this historical article from Martin Fowler about dependency injection pattern, but actually there isn’t a real framework for implement dependency injection in Delphi.

There are already the following implementation for DI in Delphi

  • Emballo (work with pre-D2010 too, but the implementation require changes in the service classes. I really hate it)
  • Delphi Spring Framework (very nice, but still not realeased)

So, I decided to write my own simple DI framework.

You can find the code at google code project here: http://code.google.com/p/delphidicontainer/

This is the first public version and come with sample, documentation and unit tests.

Folow some sample code.

  1. program Test01;
  2. {$APPTYPE CONSOLE}
  3.  
  4. uses
  5.   SysUtils,
  6.   DIContainer in '..\..\src\DIContainer.pas',
  7.   ServiceTestObjectsU in '..\..\UnitTest\ServiceTestObjectsU.pas';
  8.  
  9. var
  10.   DIContainer: TDIContainer;
  11.   s1: TService1;
  12.   s2: TService2;
  13.   s3: TService3;
  14.   s6: TService6;
  15.   s7: TService7;
  16. begin
  17.   try
  18.     DIContainer := TDIContainer.Create;
  19.     try
  20.       // AddComponent with TClass with and   InitType = Singleton
  21.       DIContainer.AddComponent(TService1, TDIContainerInitType.Singleton);
  22.       // AddComponent with QualifiedName and InitType = Singleton
  23.       DIContainer.AddComponent('ServiceTestObjectsU.TService2',
  24.         TDIContainerInitType.Singleton);
  25.       // AddComponent with QualifiedName and InitType = CreateNewInstance
  26.       DIContainer.AddComponent('ServiceTestObjectsU.TService3',
  27.         TDIContainerInitType.CreateNewInstance);
  28.  
  29.       // GetComponent with QualifiedName
  30.       s1 := DIContainer.GetComponent('ServiceTestObjectsU.TService1')
  31.         as TService1;
  32.       s1.Message := 'I''m the first message';
  33.       WriteLn(s1.Message);
  34.  
  35.       // GetComponent with TClass
  36.       s2 := DIContainer.GetComponent(TService2) as TService2;
  37.       s2.Message := 'I''m the second message';
  38.       WriteLn(s2.Message);
  39.  
  40.       // GetComponent with a dependent service (TService3 depends upon TService1 and TService2)
  41.       s3 := DIContainer.GetComponent('ServiceTestObjectsU.TService3')
  42.         as TService3;
  43.       WriteLn(s3.GetCompoundMessage);
  44.       // s3 is not created as Singleton, so after use it I must free it
  45.       s3.Free;
  46.  
  47.       // AddComponent with QualifiedClassName, a custom initializer, an alias.
  48.       // Component will be created as singleton (single instance managed by Container)
  49.  
  50.       DIContainer.AddComponent(DIContainerUtils.GetQualifiedClassName
  51.           (TService6),
  52.           function: TObject
  53.           begin
  54.             Result := TService6.Create(DIContainer.Get(TService1) as TService1,DIContainer.Get(TService1) as TService1);
  55.           end,
  56.           'srv6',
  57.         TDIContainerInitType.Singleton);
  58.  
  59.       s6 := DIContainer.Get('srv6') as TService6;
  60.       WriteLn(s6.ToString);
  61.       s6 := DIContainer.Get('srv6') as TService6;
  62.       WriteLn(s6.ToString);
  63.  
  64.       // AddComponent with QualifiedClassName, a custom initializer, an alias.
  65.       // Component will be created as singleton (single instance managed by Container)
  66.       DIContainer.AddComponent(DIContainerUtils.GetQualifiedClassName
  67.           (TService7),
  68.             function: TObject
  69.             begin
  70.               Result := TService7.Create(DIContainer.Get(TService1) as TService1,DIContainer.Get(TService1) as TService1);
  71.             end,
  72.             'srv7intf',
  73.           TDIContainerInitType.Singleton);
  74.  
  75.       s7 := DIContainer.Get('srv7intf') as TService7;
  76.       WriteLn(s7.ToString);
  77.     finally
  78.       DIContainer.Free;
  79.     end;
  80.   except
  81.     on E: Exception do
  82.       WriteLn(E.ClassName, E.Message);
  83.   end;
  84.   readln;
  85. end.

DelphiDIContainer also handle constructor injection with automatic dependency resolution for service.

Enjoy and stay tuned.

News and small fixes for DataSnap Filters compendium

DataSnap Filters Compendium 4 Comments »

DataSnap Filters Compendium has been used by many users so far. I’m planning to do some change in hash filters (that do not will affect already written code) but until new version will ready I have 3 nice news about DSFC:

1. Now the project is on Google Code.

2. Franco Perana, the first contributor to the project, has fixed and optimized the LZO filter.

3. Have you used DSFC and do you want to see your application listed in the “Application Using DSFC”? If yes, leave a comment on this post with some details of your application amd I’ll add it in the proper list.

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in