How can I model a "Select, Map, Save to local file" report in ABAP OO? - abap

The Report is required to select master data based on Selection-Screen input, map the needed fields into new export structure, transform to XML and save to local file.
Since there are multiple Reports doing to this for different types of master data I started by creating an abstract class in which I put the elements useful for all Reports and intend to create one class for each report inheriting from that class.
I then call a static method from the report which creates the instance of the report class and starts the process.
REPORT ztesten.
PARAMETERS p1 TYPE c.
PARAMETERS p2 TYPE c.
START-OF-SELECTION.
zcl_class=>main(
EXPORTING p1 = p1
p2 = p2 ).
METHOD main.
DATA(lo_class) =
NEW zcl_tradenet_export_kostl(
p1 = p1
p2 = p2 ).
lo_class->start_process( ).
ENDMETHOD.
I am struggling so far with what to use as attributes since it is generally advised to avoid using global data. Currently I store all parameters and other read only data that is selected from the database at the start of the program (this is done to avoid doing selects multiple times in loops) and then needed throughout the report as well as the export structure. If I wanted to avoid that I would have to drag them all along the call stack which seems even more impractical to me even though it uses local and not global data.
For the parameters and DB data this seems somehow ok since the attribute is only read and not changed, but as for the export structure I have more concerns since it is filled progressively. Yet dragging it along seems also impractical since it would bloat method signatures.
How would you deal with those aspects?
One final Question: Using my current approach, the number of attributes can get large fairly quickly if the selection screen has many elements or many database tables are read beforehand. Would you group them in structures to Keep the number down and make things clearer?

Create a class that provides public members to store all your parameters.
CLASS ztesten_config DEFINITION PUBLIC CREATE PUBLIC.
PUBLIC SECTION.
DATA p1 TYPE c.
DATA p2 TYPE c.
ENDCLASS.
CLASS ztesten_config IMPLEMENTATION.
ENDCLASS.
Instantiate the class and store your parameters inside.
REPORT ztesten.
PARAMETERS p1 TYPE c.
PARAMETERS p2 TYPE c.
START-OF-SELECTION.
DATA(config) = NEW ztesten_config( ).
config->p1 = p1.
config->p2 = p2.
zcl_class=>main( config ).
You can now pass that object through your call stack. This may still be annoying, but less so because it is only a single parameter. It is also the cleanest solution, because it minimizes state and coupling of your classes.
METHOD main.
DATA(lo_class) = NEW zcl_tradenet_export_kostl( ).
lo_class->start_process( config ).
ENDMETHOD.
If your objects represent processes ("bla_calculation"), not processors ("bla_calculator"), you can reduce the number of parameter passes by passing the config to the classes' constructors and letting them save in some private attribute. This requires that you instantiate the classes for each execution of the report anew.
METHOD main.
DATA(lo_class) = NEW zcl_tradenet_calculation( config ).
lo_class->start_process( ).
ENDMETHOD.
You can avoid having to pass the object through the call stack completely by applying patterns like singleton.
CLASS ztesten_config DEFINITION PUBLIC CREATE PUBLIC.
PUBLIC SECTION.
DATA p1 TYPE c.
DATA p2 TYPE c.
CLASS-METHODS get_instance
RETURNING
VALUE(result) TYPE REF TO ztesten_config.
PRIVATE SECTION.
CLASS-DATA singleton TYPE REF TO ztesten_config.
ENDCLASS.
CLASS ztesten_config IMPLEMENTATION.
METHOD get_instance.
IF singleton IS NOT BOUND.
singleton = NEW #( ).
ENDIF.
result = singleton.
ENDMETHOD.
ENDCLASS.
METHOD somewhere_inside_tradenet_export_kostl.
DATA(config) = ztesten_config=>get_instance( ).
config->p1 [...]
ENDMETHOD.
All of these patterns allow you to supply test data instead of the real report input, and to utilize your classes outside of the report context.
For the result of the report, you can follow a similar design, by producing an object that receives and stores the result data piece by piece.
Structuring parameters is always a good idea: it not only makes method signatures smaller, it also adds context which parameters belong together, and how.
Are you familiar with Clean ABAP? The section Aim for few IMPORTING parameters, at best less than three specifically recommends that "You can reduce the number of parameters by combining them into meaningful sets with structures and objects."

Related

Resolving the method of a ABAP dynamic call: order of types considered

I try to provoke a behaviour described in the ABAP Keyword Documentation 7.50 but fail. It's given with Alternative 2 of CALL METHOD - dynamic_meth:
CALL METHOD oref->(meth_name) ...
Effect
... oref can be any class reference variable ... that points to an object that contains the method ... specified in meth_name. This method is searched for first in the static type, then in the dynamic type of oref
I use the test code as given below. The static type of oref is CL1, the dynamic type CL2. Shouldn't then the dynamic CALL METHOD statement call the method M in CL1?
REPORT ZU_DEV_2658_DYNAMIC.
CLASS CL1 DEFINITION.
PUBLIC SECTION.
METHODS M.
ENDCLASS.
CLASS CL1 IMPLEMENTATION.
METHOD M.
write / 'original'.
ENDMETHOD.
ENDCLASS.
CLASS CL2 DEFINITION INHERITING FROM CL1.
PUBLIC SECTION.
METHODS M REDEFINITION.
ENDCLASS.
CLASS CL2 IMPLEMENTATION.
METHOD M.
write / 'redefinition'.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA oref TYPE REF TO cl1. " static type is CL1
CREATE OBJECT oref TYPE cl2. " dynamic type is CL2
oref->m( ). " writes 'redefinition' - that's ok
CALL METHOD oref->('M'). " writes 'redefinition' - shouldn't that be 'original'?
Update:
I'd like to answer to the (first four) comments to my original question. Because of the lengthy code snippet, I answer by augmenting my post, not by comment.
It is true that the behaviour of the code snippet of the original question is standard OO behaviour. It's also true that for calls with static method name and class, types are resolved as given by the link. But then:
Why does the ABAP Keyword Documentation make the statement I've linked?
Calls with dynamic method names do search for the method name in the dynamic type, as demonstrated by the following code piece. That's certainly not standard OO behaviour.
My question was: Apparently, the search mechanism differs from the one described. Is the description wrong or else do I miss something?
REPORT ZU_DEV_2658_DYNAMIC4.
CLASS CL_A DEFINITION.
ENDCLASS.
CLASS CL_B DEFINITION INHERITING FROM CL_A.
PUBLIC SECTION.
METHODS M2 IMPORTING VALUE(caller) TYPE c OPTIONAL PREFERRED PARAMETER caller.
ENDCLASS.
CLASS CL_B IMPLEMENTATION.
METHOD M2.
write / caller && ' calls b m2'.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA orefaa TYPE REF TO cl_a.
CREATE OBJECT orefaa TYPE cl_a. " static and dynamic type is CL_A
*orefaa->m2( 'orefa->m2( )' ). syntax error: method m2 is unknown'.
*CALL METHOD orefaa->('M2') EXPORTING caller = 'CALL METHOD orefa->("M2")'. results in exception: method m2 is unknown'.
DATA orefab TYPE REF TO cl_a. " static type is CL_A
CREATE OBJECT orefab TYPE cl_b. " dynamic type is CL_B
*orefab->m2( 'orefab->m2( )' ). results in syntax error: method m2 is unknown'.
CALL METHOD orefab->('M2') EXPORTING caller = 'CALL METHOD orefab->("M2")'. " succeeds
You are actually answering your own question there, aren't you?
In your first example, you perform a call method to the method m on a variable that's typed as cl1. The runtime looks up the class cl1, and finds the requested method m there. It then calls that method. However, your variable actually has the type cl2, a sub-class of cl1, that overrides that method m. So the call effectively reaches that redefinition of the method, not the super-class's original implementation. As you and the commenters sum it up: this is standard object-oriented behavior.
Note how in essence this has nothing to do at all with the static-vs-dynamic statement you quote from the documentation. The method m is statically present in cl1, so there is no dynamic lookup involved whatsoever. I assume you were looking for a way to probe the meaning of this statement, but this example doesn't address it.
However, your second example then precisely hits the nail on the head. Let me rewrite it again with different names to talk it through. Given an empty super class super_class:
CLASS super_class DEFINITION.
ENDCLASS.
and a sub-class sub_class that inherits it:
CLASS sub_class DEFINITION
INHERITING FROM super_class.
PUBLIC SECTION.
METHODS own_method.
ENDCLASS.
Now, as super_class is empty, sub_class does not take over any methods there. In contrast, we add a method own_method specifically to this class.
The following statement sequence then demonstrates exactly what's special with the dynamic calling:
DATA cut TYPE REF TO super_class.
cut = NEW sub_class( ).
CALL METHOD cut->('OWN_METHOD').
" runs sub_class->own_method
The runtime encounters the call method statement. It first inspects the static type of the variable cut, which is super_class. The requested method own_method is not present there. If this was all that happened, the call would now fail with a method-not-found exception. If we wrote a hard-coded cut->own_method( ), we wouldn't even get this far - the compiler would already reject this.
However, with call method the runtime continues. It determines the dynamic type of cut as being sub_class. Then it looks whether it finds an own_method there. And indeed, it does. The statement is accepted and the call is directed to own_method. This additional effort that's happening here is exactly what's described in the documentation as "This method is searched for first in the static type, then in the dynamic type of oref".
What we're seeing here is different from hard-coded method calls, but it is also not "illegal". In essence, the runtime here first casts the variable cut to its dynamic type sub_class, then looks up the available methods again. As if we were writing DATA(casted) = CAST super_class( cut ). casted->own_method( ). I cannot say why the runtime acts this way. It feels like the kind of relaxed behavior we usually find in ABAP when statements evolve throughout their lifetime and need to remain backwards-compatible.
There is one detail that needs additional addressing: the tiny word "then" in the documentation. Why is it important to say that it first looks in the static type, then in the dynamic type? In the example above, it could simply say "and/or" instead.
Why this detail may be important is described in my second answer to your question, which I posted some days ago. Let me wrap it up shortly again here, so this answer here is complete. Given an interface with a method some_method:
INTERFACE some_interface PUBLIC.
METHODS some_method RETURNING VALUE(result) TYPE string.
ENDINTERFACE.
and a class that implements it, but also adds another method of its own, with the exact same name some_method:
CLASS some_class DEFINITION PUBLIC.
PUBLIC SECTION.
INTERFACES some_interface.
METHODS some_method RETURNING VALUE(result) TYPE string.
ENDCLASS.
CLASS some_class IMPLEMENTATION.
METHOD some_interface~some_method.
result = `Executed the interface's method`.
ENDMETHOD.
METHOD some_method.
result = `Executed the class's method`.
ENDMETHOD.
ENDCLASS.
Which one of the two methods is now called by CALL METHOD cut->('some_method')? The order in the documentation describes it:
DATA cut TYPE REF TO some_interface.
cut = NEW some_class( ).
DATA result TYPE string.
CALL METHOD cut->('SOME_METHOD')
RECEIVING
result = result.
cl_abap_unit_assert=>assert_equals(
act = result
exp = `Executed the interface's method` ).
Upon encountering the call method statement, the runtime checks the static type of the variable cut first, which is some_interface. This type has a method some_method. The runtime thus will continue to call this method. This, again is standard object orientation. Especially note how this example calls the method some_method by giving the string some_method alone, although its fully qualified name is actually some_interface~some_method. This is consistent with the hard-coded variant cut->some_method( ).
If the runtime acted the other way around, inspecting the dynamic type first, and the static type afterwards, it would act differently and call the class's own method some_method instead.
There is no way to call the class's own some_method, by the way. Although the documentation suggests that the runtime would consider cut's dynamic type some_class in a second step, it also adds that "In the dynamic case too, only interface components can be accessed and it is not possible to use interface reference variable to access any type of component."
The only way to call the class's own method some_method, is by changing cut's type:
DATA cut TYPE REF TO some_class.
cut = NEW some_class( ).
DATA result TYPE string.
CALL METHOD cut->('SOME_METHOD')
RECEIVING
result = result.
cl_abap_unit_assert=>assert_equals(
act = result
exp = `Executed the class's method` ).
This is rather about interface implementations than class inheritance. What the ABAP language help means is this:
Suppose you have an interface that declares a method
INTERFACE some_interface PUBLIC.
METHODS some_method RETURNING VALUE(result) TYPE string.
ENDINTERFACE.
and a class that implements it, but alongside also declares a method with the same name, of its own
CLASS some_class DEFINITION PUBLIC.
PUBLIC SECTION.
INTERFACES some_interface.
METHODS some_method RETURNING VALUE(result) TYPE string.
ENDCLASS.
CLASS some_class IMPLEMENTATION.
METHOD some_interface~some_method.
result = `Executed the interface's method`.
ENDMETHOD.
METHOD some_method.
result = `Executed the class's method`.
ENDMETHOD.
ENDCLASS.
then a dynamic call on a reference variable typed with the interface will choose the interface method over the class's own method
METHOD prefers_interface_method.
DATA cut TYPE REF TO zfh_some_interface.
cut = NEW zfh_some_class( ).
DATA result TYPE string.
CALL METHOD cut->('SOME_METHOD')
RECEIVING
result = result.
cl_abap_unit_assert=>assert_equals(
act = result
exp = `Executed the interface's method` ).
ENDMETHOD.
This is actually the exact same behavior we are observing with regular calls to methods, i.e. if we provide the method's name in the code, not in a variable.
Only if the runtime cannot find a method with the given name in the static type will it start looking for a method with that name in the dynamic type. This is different from regular method calls, where the compiler will reject the missing some_interface~ and require us to add an alias for this to work.
By the way, as some people brought it up in the comments, the "static" here does not refer to CLASS-METHODS, as opposed to "instance" methods. "Static type" and "dynamic type" refer to different things, see the section Static Type and Dynmic Type in the help article Assignment Rules for Reference Variables.

How to read a private attribute of an object without a getter in ABAP

Is there any way to get the value of an objects' private attribute without a getter. Modifying the class is not permitted in any shape or form.
Please find below an example class with a private attribute.
CLASS counter DEFINITION.
PUBLIC SECTION.
METHODS: set IMPORTING value(set_value) TYPE i.
PRIVATE SECTION.
DATA count TYPE i.
ENDCLASS. "counter DEFINITION
CLASS counter IMPLEMENTATION.
METHOD set.
count = set_value.
ENDMETHOD. "set
ENDCLASS. "counter IMPLEMENTATION
How can I get the value of count? Inheriting from counter will not work because count is private, not protected.
Unfortunately not, I have tried this myself in many different ways none of which work:
Having a standard super class - the super class cannot access the
private attributes of subclasses dynamically
Making a subclass will never work since it can only access protected
Attempting to use the unit test framework doesn't work. I tried to
call the kernel modules that allow access to private data but to no
avail.
You are basically flat out of luck. There is one obscure option though depending on the class you are trying to access. Some classes have interfaces specified as friends and if you implement that interface you can access their private data (the ALV on 7.20 is like this) but unfortunately this will only work in a few limited cases.
Runtime type services are the abap's equivalent of reflection.
They allow You nearly to scan every object, and mostly even modify it at runtime. As far as i know, the visibility of attributes does not matter. But be careful.
And read about the various classes, because there are many, each specified to work on a special type of dataopbject ( structs, objects, etc)
http://wiki.scn.sap.com/wiki/pages/viewpage.action?pageId=42965
You could make a sub class, re-implement the setter and set a second variable, then call the parent method. Be aware of the ramifications of having two variables holding the same stuff... Please see vwegert's comments and see if you really want to because it's generally not a great idea and it breaks the rules of OO.
CLASS counter_sub DEFINITION INHERITING FROM counter.
PUBLIC SECTION.
data count2 type i read-only.
METHODS: set REDEFINITION.
ENDCLASS. "counter_sub DEFINITION
CLASS counter_sub IMPLEMENTATION.
METHOD set.
count2 = set_value.
super->set( set_value ).
ENDMETHOD. "set
ENDCLASS. "counter_sub IMPLEMENTATION

Can define variables as references to local classes defined in another program?

I have a program ZPROG1_TEST where I define a local class LCL_PROG1_HELPER.
I have a second program ZPROG2_TEST where I'd like to define a variable reference to this class.
Isn't there a syntactic possibility for me to do this?
Or could this be in theory doable with the RTTI classes like CL_ABAP_CLASSDESCR ?
EXTRA
Why I'd like to do this is because I have a custom form ZMM_MEDRUCK that needs to know if the ME32N Document it's printing has been changed but not saved.
I've figures out the exact objects whose properties I need to interogate, but some of them are defined at design time as common interfaces, like IF_SERIALIZABLE_MM, and I need to cast them to the local classes whose instances I know these objects are going to be, like \FUNCTION-POOL=MEGUI\CLASS=LCL_APPLICATION.
I could of course try a dynamic method call and not care about anything, but since i'm here i thought i'd ask this thing first.
You could do it like that.
REPORT ZPROG1_TEST.
INTERFACE lif_prog1_helper.
METHODS:
test.
ENDINTERFACE.
CLASS LCL_PROG1_HELPER DEFINITION.
PUBLIC SECTION.
INTERFACES:
lif_prog1_helper.
ALIASES:
test FOR lif_prog1_helper~test.
ENDCLASS.
CLASS LCL_PROG1_HELPER IMPLEMENTATION.
METHOD test.
WRITE / sy-repid.
ENDMETHOD.
ENDCLASS.
REPORT ZPROG2_TEST.
DATA: g_test TYPE REF TO object.
START-OF-SELECTION.
CREATE OBJECT g_test TYPE ('\PROGRAM=ZPROG1_TEST\CLASS=LCL_PROG1_HELPER').
CALL METHOD g_test->('TEST').
CALL METHOD g_test->('LIF_PROG1_HELPER~TEST').
As far as I know, this is not possible. Accessing the local class dynamically is easy (well, relatively easy), but referring to it statically - not as far as I know. You'll probably have to call the methods dynamically.

ABAP create object

Below is a code snippet that is creating object.
Form userexit_save_document_prepare.
data: /bks/exitmanager type ref to /bks/exit_manager.
create object /bks/exitmanager
exporting main_prog = 'SAPMV45A'
exit_form = 'USEREXIT_SAVE_DOCUMENT_PREPARE'.
include /bks/exitman.
ENDFORM.
I got this from the documentation
For performance reasons, the parameters "main_prog" and "exit_form" should be filled, in the case of userexits, which are performed very often like "user_field_modification" in "SAPMV45A" which is called for every single screen-field.
1) What happened exactly behind when create object /bks/exitmanager is called? memory allocated for the object etc?
2) Why for performance reasons the exporting parameters of create object needs to be filled?
I'm not 100% sure, but here is my best guess:
an object called /bks/exitmanager is constructed (which is an oject of the class /bks/exit_manager or more specific a reference/"pointer" to an object of this class) .. the required memory allocated etc., but also the "constructor" code is called (probably sets some instance variables as passed to the call).
If you're explicitly passing these parameters, they don't have to be "calculated" at run-time (e.g. by looking at the call stack). This should save some time, especially if it would have to be done quite often (as described in the documentation).
It would help to see what /bks/exit_manager actually is, and a brief explanation of what you are trying to accomplish.
Expanding on what IronGoofy wrote:
data: /bks/exitmanager type ref to /bks/exit_manager
This creates a reference pointer in the ABAP memory of your program, much like a field symbol. Also it must be already delared. If it is in the include, you need to move the include.
create object /bks/exitmanager
exporting main_prog = 'SAPMV45A'
exit_form = 'USEREXIT_SAVE_DOCUMENT_PREPARE'.
This creates an object instance based on the declared class, and assigns it to the referance pointer. It does this by calling the constructor method first.
Only by examing /bks/exit_manager will you find out exactly what you need to export.
It's impossible to tell what's going on and why the parameters should be passed without taking a look at the constructor of /BKS/EXIT_MANAGER. It's a common pattern though to keep a buffer of settings (think of a static hashed table with the key being the parameters and the value holding whatever is complicated and time-consuming to fetch). In this case, I would have expected a protected constructor that cannot be accessed directly, but only using a static factory method that uses a hashed table to keep the references of the exit handler itself - optimally using weak references...

God object - decrease coupling to a 'master' object

I have an object called Parameters that gets tossed from method to method down and up the call tree, across package boundaries. It has about fifty state variables. Each method might use one or two variables to control its output.
I think this is a bad idea, beacuse I can't easily see what a method needs to function, or even what might happen if with a certain combination of parameters for module Y which is totally unrelated to my current module.
What are some good techniques for decreasing coupling to this god object, or ideally eliminating it ?
public void ExporterExcelParFonds(ParametresExecution parametres)
{
ApplicationExcel appExcel = null;
LogTool.Instance.ExceptionSoulevee = false;
bool inclureReferences = parametres.inclureReferences;
bool inclureBornes = parametres.inclureBornes;
DateTime dateDebut = parametres.date;
DateTime dateFin = parametres.dateFin;
try
{
LogTool.Instance.AfficherMessage(Variables.msg_GenerationRapportPortefeuilleReference);
bool fichiersPreparesAvecSucces = PreparerFichiers(parametres, Sections.exportExcelParFonds);
if (!fichiersPreparesAvecSucces)
{
parametres.afficherRapportApresGeneration = false;
LogTool.Instance.ExceptionSoulevee = true;
}
else
{
The caller would do :
PortefeuillesReference pr = new PortefeuillesReference();
pr.ExporterExcelParFonds(parametres);
First, at the risk of stating the obvious: pass the parameters which are used by the methods, rather than the god object.
This, however, might lead to some methods needing huge amounts of parameters because they call other methods, which call other methods in turn, etcetera. That was probably the inspiration for putting everything in a god object. I'll give a simplified example of such a method with too many parameters; you'll have to imagine that "too many" == 3 here :-)
public void PrintFilteredReport(
Data data, FilterCriteria criteria, ReportFormat format)
{
var filteredData = Filter(data, criteria);
PrintReport(filteredData, format);
}
So the question is, how can we reduce the amount of parameters without resorting to a god object? The answer is to get rid of procedural programming and make good use of object oriented design. Objects can use each other without needing to know the parameters that were used to initialize their collaborators:
// dataFilter service object only needs to know the criteria
var dataFilter = new DataFilter(criteria);
// report printer service object only needs to know the format
var reportPrinter = new ReportPrinter(format);
// filteredReportPrinter service object is initialized with a
// dataFilter and a reportPrinter service, but it doesn't need
// to know which parameters those are using to do their job
var filteredReportPrinter = new FilteredReportPrinter(dataFilter, reportPrinter);
Now the FilteredReportPrinter.Print method can be implemented with only one parameter:
public void Print(data)
{
var filteredData = this.dataFilter.Filter(data);
this.reportPrinter.Print(filteredData);
}
Incidentally, this sort of separation of concerns and dependency injection is good for more than just eliminating parameters. If you access collaborator objects through interfaces, then that makes your class
very flexible: you can set up FilteredReportPrinter with any filter/printer implementation you can imagine
very testable: you can pass in mock collaborators with canned responses and verify that they were used correctly in a unit test
If all your methods are using the same Parameters class then maybe it should be a member variable of a class with the relevant methods in it, then you can pass Parameters into the constructor of this class, assign it to a member variable and all your methods can use it with having to pass it as a parameter.
A good way to start refactoring this god class is by splitting it up into smaller pieces. Find groups of properties that are related and break them out into their own class.
You can then revisit the methods that depend on Parameters and see if you can replace it with one of the smaller classes you created.
Hard to give a good solution without some code samples and real world situations.
It sounds like you are not applying object-oriented (OO) principles in your design. Since you mention the word "object" I presume you are working within some sort of OO paradigm. I recommend you convert your "call tree" into objects that model the problem you are solving. A "god object" is definitely something to avoid. I think you may be missing something fundamental... If you post some code examples I may be able to answer in more detail.
Query each client for their required parameters and inject them?
Example: each "object" that requires "parameters" is a "Client". Each "Client" exposes an interface through which a "Configuration Agent" queries the Client for its required parameters. The Configuration Agent then "injects" the parameters (and only those required by a Client).
For the parameters that dictate behavior, one can instantiate an object that exhibits the configured behavior. Then client classes simply use the instantiated object - neither the client nor the service have to know what the value of the parameter is. For instance for a parameter that tells where to read data from, have the FlatFileReader, XMLFileReader and DatabaseReader all inherit the same base class (or implement the same interface). Instantiate one of them base on the value of the parameter, then clients of the reader class just ask for data to the instantiated reader object without knowing if the data come from a file or from the DB.
To start you can break your big ParametresExecution class into several classes, one per package, which only hold the parameters for the package.
Another direction could be to pass the ParametresExecution object at construction time. You won't have to pass it around at every function call.
(I am assuming this is within a Java or .NET environment) Convert the class into a singleton. Add a static method called "getInstance()" or something similar to call to get the name-value bundle (and stop "tramping" it around -- see Ch. 10 of "Code Complete" book).
Now the hard part. Presumably, this is within a web app or some other non batch/single-thread environment. So, to get access to the right instance when the object is not really a true singleton, you have to hide selection logic inside of the static accessor.
In java, you can set up a "thread local" reference, and initialize it when each request or sub-task starts. Then, code the accessor in terms of that thread-local. I don't know if something analogous exists in .NET, but you can always fake it with a Dictionary (Hash, Map) which uses the current thread instance as the key.
It's a start... (there's always decomposition of the blob itself, but I built a framework that has a very similar semi-global value-store within it)