Skip to Content
Author's profile photo Paul Hardy

Shoot Me Up ABAP

Dependency Injection


There is many a true word, Spoken Inject

One line summary:-

One way to write OO programs with many small classes with less lines of code.

Back Story

The other day there was a blog on SCN about Dependency injection.

I thought – I know what that is – if an object (say a car object) needs an engine object to work, you don’t have the car object create the engine object, you pass in the engine object through the car objects constructor.

I had thought that was solely concerned with unit testing, but if you look at the comments at the bottom, when I started talking about this on the blog comments, people soon put me right, it turns out it has a much wider scope.

As soon as I realised I was barking up the wrong tree, I read all I could on the subject, for example …

… ending with this blog by Jack Stewart

I always thought the idea was great – often you have to create a bunch of objects and then “wire them together” by passing them into each other’s constructors so they know about each other.

This gives you the flexibility to pass in subclasses to alter the behaviour of the application – as I said I had first heard about this in the context of unit testing, but when I thought about it again naturally you can pass in any sort of subclass to change the way the program runs e.g. different subclass based on whatever criteria makes sense, just like the BADI filter mechanism.

That is a wonderful thing to be able to do, and subclassing is one of the few benefits of OO programming that one of my colleagues can get his head around, but it does tend to involve a lot of “boiler plate” programming i.e. lots of CREATE OBJECT statements, passing in assorted parameters.

Many Small Classes, make Light Work

The idea is that the smaller and more focused your classes are, the easier they are to re-use and maintain. An OO principle is that a class should only have one reason to change i.e. it should do one thing only. If you follow that principle you get loads of benefits, but you have to create loads of classes in your program.

When I first started playing around with OO programming I was too lazy to keep writing CREATE OBJECT so I made everything static. That is not actually a sensible thing to do just to avoid work, as then you can’t subclass things. SAP itself found that out when they initially made ABAP proxy classes static.

The NEW Objects on the Block

In the Java programming language you create objects by saying GOAT = NEW GOAT as opposed to CREATE OBJECT GOAT.

In the “Head First Design Patterns Book” it gives a bunch of about five rules of programming which every Java programmer should aspire to but are in fact impossible to follow in real life.

One of those revolved around the rule being never to use the NEW statement because that hard coded the exact type of class you were creating, but how can you create objects if the only way to create them is to use the NEW statement?

In both Java and ABAP interfaces come into play here, you declare the ANIMAL object as an interface of type FARM ANIMAL (which GOAT implements) and say CREATE OBJECT ANIMAL TYPE GOAT. Perhaps a better example is in ABAP2XLS when you declare the object that writes out the file as an interface and then create it using the TYPE of the EXCEL version you want e.g. 2007.

Now you are always going to have to say the specific type (subclass) you want somewhere, but is it possible to decouple this from the exact instant you call the CREATE OBJECT statement?

Since you can have a dynamic CREATE OBJECT statement, you would think so, but how does this apparent diversion link back to what I was talking about earlier?

Jack Black and his blog Silver

Going back to Dependency Injection the blog by Jack Stewart contained a link to download some sample code. I downloaded it, had a look, thought it was great, and then totally re-wrote it. That is no reflection on the quality of the original; I am just physically incapable of not rewriting every single thing I come across.

I am going to include a SAPLINK file in text format at the end of this blog, but first I shall go through the code, top down. Firstly, this test program shows exactly what I am trying to achieve i.e. the same thing in less lines of code.

I have created some dummy Y classes which just have constructors to pass in a mixture of object instances and elementary data object parameters, my dear Watson. They only have one method each, just to write out if they are a base class or a subclass. The important thing is the effort involved to create them.

The Da Vinci Code Samples

First of all, a basic structure to get some elementary parameters and say if we want to use a test double or not. I am sticking with the unit test concept for now, but as I mentioned, you can pass in any old subclass you want, according to the good old, every popular, Liskov Substitution principle.

* Show two ways to create linked objects, one using dependency injection
REPORT  y_injection_test.

PARAMETERS : p_valid TYPE sydatum,
TYPE werks_d,

= sydatum.
= ‘3116’.

PERFORM do_it_the_long_way.
PERFORM do_it_the_short_way.

It’s a Long Long Way, from there to here

Firstly, the traditional way….

*&      Form  DO_IT_THE_LONG_WAY
* Normal way of doing things
FORM do_it_the_long_way .
DATA: lo_logger        TYPE REF TO ycl_test_logger.
DATA: lo_db_layer      TYPE REF TO ycl_test_db_layer.
DATA: lo_mock_db_layer TYPE REF TO ycl_test_mock_db_layer.
DATA: lo_simulator     TYPE REF TO ycl_test_simulator.

  CREATE OBJECT lo_logger.

  IF p_test = abap_true.

    CREATE OBJECT lo_mock_db_layer
= lo_logger
= p_valid.

    CREATE OBJECT lo_simulator
= p_werks
= lo_mock_db_layer
= lo_logger.


    CREATE OBJECT lo_db_layer
= lo_logger
= p_valid.

    CREATE OBJECT lo_simulator
= p_werks
= lo_db_layer
= lo_logger.


  lo_simulator->say_who_you_are( ).


ENDFORM.                    ” DO_IT_THE_LONG_WAY

Get Shorty

Now we do the same thing, using a Z class I created to use dependency injection.

*&      Form  DO_IT_THE_SHORT_WAY
*  Using Constructor Injection
FORM do_it_the_short_way .
* Local Variables
DATA: lo_simulator  TYPE REF TO ycl_test_simulator.

  zcl_bc_injector=>during_construction( :
= ‘ID_PLANT_ID’ use_value = p_werks ),
= ‘ID_VALID_ON’ use_value = p_valid ).

  IF p_test = abap_true.
“We want to use a test double for the database object
=>instead_of( using_main_class = ‘YCL_TEST_DB_LAYER’

  zcl_bc_injector=>create_via_injection( CHANGING co_object = lo_simulator ).

  lo_simulator->say_who_you_are( ).

ENDFORM.                    ” DO_IT_THE_SHORT_WAY

I think the advantage is self-evident – the second way is much shorter, and it’s got Big Feet.

If the importing parameter of the objectconstructor was an interface it would not matter at all. You just pass the interface name in to the INSTEAD_OF method as opposed to the main class name.

I have done virtually no error handling in the below code, except throwing fatal exceptions when unexpected things occur. This could be a lot more elegant, I am just demonstrating the basic principle.

Firstly the DURING CONSTRUCTION method analyses elementary parameters and then does nothing more fancy than adding entries to an internal table.

* Local Variables
DATA: lo_description       TYPE REF TO cl_abap_typedescr,
TYPE string ##needed,
TYPE string,
LIKE LINE OF mt_parameter_values.

  ls_parameter_valuesidentifier = for_parameter.

  CREATE DATA ls_parameter_valuesdo_value LIKE use_value.
GET REFERENCE OF use_value INTO ls_parameter_valuesdo_value.

  CHECK sysubrc = 0.

  CALL METHOD cl_abap_structdescr=>describe_by_data_ref
= ls_parameter_valuesdo_value
= lo_description
= 1
OTHERS               = 2.

  IF sysubrc <> 0.

  SPLIT lo_description->absolute_name AT ‘=’ INTO ld_dummy ld_data_element_name.

  ls_parameter_valuesrollname = ld_data_element_name.

  INSERT ls_parameter_values INTO TABLE mt_parameter_values.

It’s the same deal with the INSTEAD_OF method for saying what exact subclass you want to create, except it’s even simpler this time.

METHOD instead_of.
* Local Variables
DATA: ls_sub_classes_to_use LIKE LINE OF mt_sub_classes_to_use.

  ls_sub_classes_to_usemain_class = using_main_class.
sub_class  = use_sub_class.

  “Add entry at the start, so it takes priority over previous
“similar entries
INSERT ls_sub_classes_to_use INTO mt_sub_classes_to_use INDEX 1.


Now we come to the main CREATE_BY_INJECTION method.  I like to think I have written this as close to plain English as I can, so that this is more or less elf-explanatory.

METHOD create_via_injection.
* Local Variables
DATA: lo_class_in_reference_details  TYPE REF TO cl_abap_refdescr,
TYPE REF TO cl_abap_typedescr,
TYPE REF TO cl_abap_typedescr,
TYPE seoclassclsname,
TYPE seoclassclsname,
LIKE LINE OF mt_created_objects,
TYPE abap_parmbind_tab.

* Determine the class type of the reference object that was passed in
  lo_class_in_reference_details ?= cl_abap_refdescr
=>describe_by_data( co_object ).
= lo_class_in_reference_details->get_referenced_type( ).
= lo_class_in_type_details->get_relative_name( ).

  “See if we need to create the real class, or a subclass
= ld_class_passed_in
= lo_class_in_type_details
= ld_class_type_to_create
= lo_class_to_create_type_detail ).

  READ TABLE mt_created_objects INTO ls_created_objects WITH TABLE KEY clsname = ld_class_type_to_create.

  IF sysubrc = 0.
“We already have an instance of this class we can use
    co_object ?= ls_created_objects

  “See if the object we want to create has parameters, and if so, fill them up
( EXPORTING io_class_to_create_type_detail = lo_class_to_create_type_detail
IMPORTING et_signature_values            = lt_signature_values ).

( EXPORTING id_class_type_to_create = ld_class_type_to_create
= lt_signature_values       ” Parameter Values
CHANGING  co_object               = co_object ).              ” Created Object


There is not a lot of point in drilling into this any further – I would encourage you to download the SAPLINK file, and then run this in debug mode to see what is happening.

In summary, I am always on the lookout for ways to reduce the so called “boiler plate” code, so the remaining code can concentrate on what the application is supposed to be doing as opposed to how it is doing it. This dependency injection business seems ideally suited so this purpose.

Now, while I am here.


Did I mention I am giving a speech at the “Mastering SAP Technology 2014” conference at Melbourne on the 31/03/2014 – it’s about unit testing of ABAP programs.

What’s that? I’ve already mentioned this? Many times?

Oh dear, that must have slipped my mind. In that case I won’t go on about it, and I’ll sign off.

Cheersy Cheers


Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Krishna Chaitanya
      Krishna Chaitanya

      Hi Paul,

      Nicely drafted...good one. Thanks for sharing it to all of us.


      Krishna Chaitanya.

      Author's profile photo Fábio Luiz Esperati Pagoti
      Fábio Luiz Esperati Pagoti

      Hi Paul!

      It's impossible to comment on this blog post without mentioning mockA.

      This is a mock framework created by Uwe Kunath to "mock" (aka instantiate) objects for you. In other words, a way of avoiding the "CREATE OBJECT" statement.

      It works a little bit different than your zcl_bc_injector class by the concept it pretty much the same: abstract class instantiation to use them inside other classes (dependecy injection).

      Taking this opportunity as a chance, project ABAP Workbench Objects Framework is using mockA quite a lot on its unit tests. And trust me, it saves tons of lines of code.

      By the way, WB Objects is another example of a framework with many classes and are small and can be reused. SAPLink itself is an application that could benefit from it. If you check SAPLink code, the logic to create XMLs (called Nuggs) is mixed with the selection logic of workbench objects details: classes doing more than one stuff.

      WB Objects abstracts workbench objects (many of them already including global and local classes and interfaces). It's possible to use it to for example, find of subclasses given a parent class.

      Thanks for bringing such an important topic in the community again.


      Author's profile photo Paul Hardy
      Paul Hardy
      Blog Post Author


      If you drill into that blog referenced right at the top of the blog, you will see the blog is all about dependency injection, and one of the first comments is from me asking if he had ever heard of MOCKA.

      Then the next few comments tell me that DI is not just about unit testing and directed me to a few more blogs (listed above also). After reading them I thought just to get the concept clear in my head I would have a look at creating (modifying as it turned out) a tool to inject both mock objects for testing in development and real objects for varying program behavior in production.

      I am going to be looking at MOCKA a lot this year however, and I will also have a look at your WB_OBJECTS framework. Since code exchange went away it seems a bit more difficult to get an easy overview of all the assorted projects going on by different people / teams. If there IS an easy way to get such an overview of assorted live community projects can you point me at it?

      Cheersy Cheers


      Author's profile photo Fábio Luiz Esperati Pagoti
      Fábio Luiz Esperati Pagoti

      Heu Paul!

      Yes, definitely dependency injection is a major capability OO in gereral and not only when doing unit testing. I am reading Heads First OO Analysis and Design which is really good as well. There are more examples over there.

      Talking about how to find frameworks or other projects... well.. I was not a huge fan of Code Exchange and IMHO there is no competitor for GitHub nowadays when it comes to open source repositories.

      So, I always take a look on GitHub to see what's going on.


      Author's profile photo Dmitry Volkov
      Dmitry Volkov

      Hello Paul Hardy


      I've noticed that there should be a file attached with the complete coding which is not available any more.

      Is it possible to put the complete source code here as well if you still own one?


      Thank you!

      Best regards,


      Author's profile photo Enno Wulff
      Enno Wulff

      Hey Paul Hardy

      I am also interested in following your advice:

      There is not a lot of point in drilling into this any further – I would encourage you to download the SAPLINK file, and then run this in debug mode to see what is happening.

      I wonder if you could provide the missing file for ZCL_BC_INJECTOR?

      Thanks and have a good start in 2023! 🍀

      /edit: Found it in the github repo of Tapio Reisinger Thanks for it, Tapio!