Entity Initialization

Wagner,


Up to know I was happy with the centralized factory that I have created for the Entities. I use it fo the TDataSet and for "manual" direct operations.

However I left behind the case where the data comes from Find, returning a Criteria or a Cursor.

I have created an object to transport these results from the different tiers of the software:



  INaharDataView = interface
    ['{A98D1B38-5F9E-4C9A-844B-66FF349E4055}']
    procedure   SetAsSourceCriteria(const Value: TCriteria);
    procedure   SetAsSourceCursor(const Value: ICriteriaCursor);
    procedure   SetAsSourceList(const Value: TObject);
    procedure   SetAsSourceObject(const Value: TObject);
    function    GetAsSourceCriteria: TCriteria;
    function    GetAsSourceCursor: ICriteriaCursor;
    function    GetAsSourceList: TObject;
    function    GetAsSourceObject: TObject;
    function    IsEmpty: Boolean;
    property    AsList: TObject read GetAsSourceList write SetAsSourceList;
    property    AsObject: TObject read GetAsSourceObject write SetAsSourceObject;
    property    AsCursor: ICriteriaCursor read GetAsSourceCursor write SetAsSourceCursor;
    property    AsCriteria: TCriteria read GetAsSourceCriteria write SetAsSourceCriteria;
  end;


Then the Model layer creates and sets the proper result, sometimes is AsCriteria or AsCursor. 

Then the viewer get that on the TAureliusDataSet. It is just a transport, for now.

However I need to initialize the Entities. The entities are created by Aurelius without father and mother :)

I believe that for the cases AsList and AsObject I have real entities constructed already.

But what about AsCursor and AsCriteria? if I understand those are only guidelines to retrieve the entities, it is not constructed entities yet.

otherwise, I could use a singleton and from the constructor of the entity get a way to retrieve contextual information.

But that is a problem also, since I have a multi thread environment, and many contexts. This solution only works if I have only one context only.

For example, when getting a TCriteria and setting it to the TAureliusDataSet it will be ready to share the data, and connected to a bindsource I have the TListView going thru all the records showing the values. At this moment there are some information that needs to be prepared according the context that is unknown by the entity since was created by Aurelius.

Any clues?

Eduardo, note that Aurelius already works with an object factory. However, for now it's a singleton (TObjectFactory.Instance). in future (and we might consider doing it soon if it works for you), we will replace the singleton by instances you can inherit from (or interfaces you might implement, doesn't matter now). 

Initially, we consider that this object factory should be passed to the mapping setup, thus each mapping setup/mapping explorer will have its own object factory that you can provide/implement.
Will this work for you? Or do you need extra data context? In this case, I wonder how it would work.
I have a IContext that I create based on the user login. After that I try hard to be always using Dependency Injection, not only because the good approach but because the threads that runs in Contexts. 

My context control is related to the model created. For each model I create a TObjectManager, so I believe that it should be injected to the TObjectManager instead. I have only one TMappingExplorer for the current thread. But I can have many TObjectManagers for each thread with different Contexts.

That could be passed by the constructor of TObjectManager

    constructor Create(Connection: IDBConnection; AExplorer: TMappingExplorer); override;

Adding a new parameter for the factory.

Of could be using Property injection, then I can override this class, and override the constructor to create and inject the property of the factory.

That would be very nice.

But until you bake this, do you see a workaround to get those Entities initialized? I need to give them information that are context based, BEFORE it show anything on the TListView.

thanks

I don't see a workaround since the object factory is singleton. 

hmmm.. I will try to use the current Thread ID as an indicator. Since I create the context at beginning of a thread (or the main thread) I can store the Pair <Thread ID, Context> in a singleton and the entity created by Aurelius can lookup for the correspondent pair, since it can get the current Thread ID either. 


Eventually will work, until I wait for a DI factory on Aurelius ! 

This is why singletons are evil, but hard to not have few of them ! My factories are all singletons.