Under construction
Some definitions for an application-core under .NET framework using WPF/ORM-Framework/SQL-Server
Lifetime service
The framework supplies object initialization and termination in hirarchically organized ownership models. It can optionally track lifing objects. It manages recursive termination of all child objects when a parent object is terminated.
Service Container features for Dependency Injection [DICont]
The framework supplies various implementations of dependency injection containers to supply services [DiService] identified by a System.Type.
local service dependency injection container [LocalDICont].
This is the most simple implementation of a service container which is just a mapping from an SystemType object representing a service interface to an system.object which represents the service implementing the interface.
virtual services dependency injection container [VirtualDICont].
A special [DiCont] implementation allows to make services available for all child objects. Using this feature services can be routed through object hirarchies from a root-level service provider to a nested-level service user where objects in the middle do not neet do declare code to forward services to child objects. Using this features various dependencies and delegation code can be elimanted.
redirected service dependency injection container [RedirectedDICont].
A special [DiCont] implementation allows to install redirectors for services. So if you request a type of service this object is not registered directly as a service in the container but an supplier object is registered which grants access to the service object. this is used for on demand loading of services.
service container fasade feature [RedirectedDICont].
The facade [Facade] composes the [LocalDICont], [VirtualDICont] and [RedirectedDICont] making it transparent to the client wether the service her requests is a local, virtual or redirected service.
[CmdExecCalc], [CmdAvailCalc], [CmdErrCalc]
[todo]
Property-Object feature [Prop], [PropObj]
The framework supplies a generic property which can be configured to implement various property strategies. VArious properties can be arranged to a property object. The framework can connect to any property so no special base class is required to use for objects can be bound to the framework. This feature is required for the [OrmAdapter]
Property's object model [PropOM]
Properties can contain objects of other [PropObj] objects. The framework supports managing such [PropOM] object models.
Propertiys dynamic implementation feature [PropDyn]
The property implementations can run in dynamically allocated property objects.
propertys code generation feature [PropGen]
All code for properties can be generated to replace dynamically [PropDyn] objects.
Property's buffer feature: [PropBuf]
A property can be configured to use a buffer.
Property's service feature: [ServicePropBuf]
A [PropBuf] can be connected to a service. The framework will then set the [PropBuf] to a service received from a [DICont].
Property's r/w feature: [PropRead] [PropWrite]
A Property can be configured to supply read and/or write operations.
Property's change notification feature. [PropObserve]
The property can be configured to generate code for change notification which includes code to adapt the Microsoft Windows Presentation foundation observer implemenation. (System.ComponentModel.INotifyPropertyChanged). This feature is available for [PropR] and [PropW] properties.
Property's lazy load feature: [PropLazyLoad]
The [Prop] can be configured to implement a lazy load strategy where a user defined calculation routine [PropInternalCalc] can be connected. The [PropInternalCalc] is called whenever a client requests the value of a property whichs buffer is set to 'not loaded'. [PropBufNotLoaded], [PropBufLoaded]
Property's auto-refresh feature: [PropRefresh]
The framework implements a input-value-dependency-recorder [IVDR]. The recorder is activated whenever the [PropRead] interceptor catches such events.
There are following conditions:
- The property was called from an external client (for example a graphical user interface connected to a view-model) In this case the [IVDR] will record nothing.
- The property was called from a [PropInternalCalc] routine In this case the [IVDR] will record a property to use an input value.
Whenever a recorded input value is changed using [PropOBserve] the calculated properties buffer is reset to [PropBufNotLoaded] Afterward a change-event is sent via [PropObserve]. If a client is observing the property it will request the property value which again causes calling the [PropInternalCalc] routine to recalculate the property value.
Propertiys user calculation routine [PropUDCalc]
By default the [PropInternalCalc] is connected to a user defined calculation routine used to calculate values for properties. For example a [PropUDCalc] can be implement to calculate the total amount of a bill.
Properties default value ffeature [PropDefCalc]
Properties can be configured to use to use a routine for calculating default values. The [PropDefCalc] routine is called from [PropInternalCalc] if a domain object was newly created on the user interface. For example a [PropDefCalc] can implement a number generator to supply a value for a new customer.
Properties new declaration feature [PropNewCalc]
Properties can be configured always to contain a valid object avoiding Null-reference exceptions. This feature comes close to the 'New' declaration in vb6. (See the difference to the new-declaration in vb.net: In vb.net a object will not be re-created after it was set to nothing. The difference to the vb-language feautre is that the user can implement a [PropUDNewCalc] method for user defined creating objects.
Propertie's inheritance feature [PropInherit]
Properties can be automatically inherited from lower level objects. For example in a typical application looking at [PropObj] objects you have at least model layer and a view-model layer. [MVVM] In a typicall enterprise application you have an additional [ORMLayer]. Now the framework can inherit properties to generate code for your view model to read values from the model layer which again reads them from the [ORM]-layer. Doing so you get an application which provides a user interface to edit, load and save data from/to a relational database. For this you do not have to write code to redifne properties in the view-model or in the model.
Properties validation feature [PropValCalc]
Propertys can be configured to call a user defined property value validation rule. [PropValCalc] This validation rule is called by the framework in various cases. For example it is called before a property value is written. However, depending on the client some values don't have to be checked. Consider a graphical user interface where a user can select values from a predefined list. [PreDefList] In this case the validation rule for the value needs to be included in the list is not required to be executed. Now consider a data import from another system. In this case you should run all available validation rules to ensure the data imported will not cause your system or your business-workflow to be corrupted. Similar cases apply to date values which can/must contain or not contain various details. For example a date/time must may or must not contain a time but (only) a date. If you use Date/Time gui editors friend to the framework these checks are not necessarry. More complex and more expensive checks will occur when looking at business objects like an order, a shipping or things like that.
Propertys predefined list feature [PreDefList]
A special validation rule [PropValidate] exists to check for predefined values. However, these lists can be automatically mapped to the user interface.
Propertys validation rule forwarding
(todo)operation abstraction [OP]
There exists an abstraction layer for all calculation routines ([PropInternCalc], [PropUDCalc], [PropNewCalc], [PropValCalc] (...)) This abstraction layer includes also command routines [CmdExecCalc], [CmdAvailCalc], [CmdErrCalc].
Asynchronous [OP] feature.
This whole section is proprietary. Especially problems arising from combining various [AsyncMirror]-Modes must be identified. The feature matrix may not include all [AsyncMirror]-Modes described herein.
any [OP] operation can be declared to run asynchronously. [AsyncOp] In this case a property-client will trigger the process in the client-thread [ClientThread] when it invokes an [OP] on the supplier object. [AsyncSupObj] The framework will open up a thread-context for a background-worker [BwThread] in which the [Op] is executed.
Have a look at the difference between Backgroundworker oriented Multithreaded programme [BwMultiThreading] [MicrosoftBWPhiliosphy] and message-oriented//state-based multithreaded programming [MsgMultiThreading]. The framework supports a combinatation of both paradigmas. MsgMultiThreading is primarly used in [ProgressAsyncPropMirror] where it is implemented by [BwMultiThreading] However to implement [InstructionAsyncPropMirror] a [message queue] has to be implemented.
Before the [BWThread] context is opened various mirror objects will be created. Each mirror object in the [BWThread] represents a mirrorred object from the client thread. [MirrorObj] [MirroredObj] This mirror objects will be passed to the [BWThread] context so the [OP] executed asynchronously can use them. There is no on demand requesting mirrored objects by the [BWThread] from the [ClientThread] planned for now as it is not required in the concept, however, this would require the Framework implementation to use [MsgMultiThreading]
Async-mirroring of Services [DIservice]
The [BWThread] context contains mirrored representations of any service used by the calculation routine. [IVDR], [ServicePropBuf] To support this operation, services must implement the ICreateAsyncServiceMirror interface.
The standard use case for this the service which manages the [OrmObjContext]. The ICreateAsyncServiceMirror will need to clone the object and copy the connection string. [DbConString] This allows to open new ORM-Object-Context [OrmObjContext] in the [BWThread].
Async mirroring of [PropObj] objects. [PropAsyncMirror]
First there will be a [clone] of the [AsyncSupObj] which will be sent to the [BWThread] for execution.
There are serveral strategies a [Prop] can be mirrored:
-
No-Prop-Mirror
In this case it is not possible to read or write an value from this property in the [BWThread].
recalculated asnyc property mirror [RecalcAsyncPropMirror]
In this case the properties in the [BWThread] will remain in [PropBufNotLoaded] state causing a [PropInternCalc] in the [BWThread]. This may load values from the [Db] which is quite critical in order you may get inconsistent states. It has to be verified if [RecalcPropMirror] is implemented.
If this mode is exclusive and not combined with [ProgressAsyncPropMirror] property values can only be read in the [BWContext].
-
copy-loaded-async prop mirror [CopyLoadedAsyncPropMirror]
In this case property values used by the calculation routine will be calculated in the [ClientThread] and transported to the [BWThread]. There may be conditions in the [PropInternCalc] routine which in various cases requires different input values. We need to know all input values to be copied to the [BwThread] context. Either the depending properties may be manually defined or a learning routine may use the [IVDR] executed within a testcase to learn all properties need to be copied to the [BWThread].
However, in this mode only properties with [PropBufLoaded] state are copied. Other propertie's [PropInternCalc] are assumed to calculate the same value [PropInternCalc] or a value that is adequate in a asynchronous process.
If this mode is exclusive and not combined with [ProgressAsyncPropMirror] property values can only be read in the [BWContext].
-
client-loaded async prop mirrior [CopyForceClientCalcAsyncPropMirror]
This mode is similar to [CopyLoadedAsyncPropMirror] with the only difference, that [PropBufNotLoaded] values are loaded in the [ClientThread]. This is required for values calculated depending on input values from a view model. However, also this can be learned from [IVDR] executed from within a testcase.
If this mode is exclusive and not combined with [ProgressAsyncPropMirror] property values can only be read in the [BWContext].
-
progress-asnyc-prop-mirror [ProgressAsyncPropMirror]
In this mode property progress-values [ProgressVal] can be written in the [BWContext]. The new value effects the [PropBuf] of the [MirrorObj] which may cause recalc of other properties [PropRefresh] all running in the [BWThread]. The new value is also sent to the [ClientThread] where it will effect the [PropBuf] state of the [MirroredObj]. Analog [PropRefresh] sequences may be triggered in the [ClientThread].
So writting a [ProgressVal] in the [BwThread] will first effect the state of the [MirrorObj] and (a little later) the state of the [MirroredObj]. [MirrorState], [MirroredState]. [AsyncStateInconsistent] can occur during these operations.
-
Instruction-async-prop-mirror [InstructionAsyncPropMirror]
In this mode to the [MirroredState] will be transmitted to the [BWThread]. (reverse to the [ProgressAsyncPropMirror]. Again the [AsyncStateInconsistent] may occur.
[AsyncStateInconsistent]
In [ProgressAsyncPropMirror] there is a special case where a user has modified the [MirroredState] while the [ProgressVal] was calculated. This may cause the writting the [ProgressVal] to the [MirrorObj] to succedd but writting the [ProgressVal] to the [MirroredObj] will fail. A similar case causes this state during [InstructionAsyncPropMirror] operations.
[AsyncStateInconsistentBwAbort]
In case of [AsyncStateInconsistent] the [BWThread] has to be aborted and no more [ProgressVals] can be accepted to effect the [PropBuf] of the [MirroredObj].
[AsyncStateInconsistentSavePrevention]
In [AsyncStateInconsistent] optionally the [MirroredObj] can be set to a inconsistent state [MirroredObjInconsistent] where it is not allowed to be saved or modify persistent objects. However, if persistent objects have allready been modified they must be optionally prevented from beeing saved until the [BWTherad] terminated successfully. Defining these rules are very application specific and it is error prone for application developers to do this.
[AsyncStateInconsistentNoPersistModifyPrevention]
The framework may support to detect cases where [ProgressVal] effect the persistent state of an object and disallow this. This will avoid problems arising from missing [AsyncStateInconsistentSavePrevention]. This will cause the [AsyncStateInconsistentBwAbort] to take effect.
Bi-directional Active object support [ActObj], [BiDiActObj]
Active objects require a state machine in order to work properly. These state machines may be composed using the folliwing events:
-
Property [Prop].AsyncReadIsPending
this property designates wether the property value is currently asyncronously laoded. [AsyncOp][PropInternCalc]
-
Property [Prop].AsyncWriteIsPending
this property designates wehter the property value is currently transmitted to the other thread using [
-
[todo] events
Active-object networks
A simple case is an active object star-network [NetworkTopologies]. When nodes of the star start to open up [BiDiActObj] communications in a mesh or fully connected network this is very hard to control at some point. When doing so problems like deadlooks and race conditions start to become error causes. Thus such a terminology is not recommended and should not be required in our system. Compare the [BwMultiThreading].
[OrmAdapter]
[Todo]
Literature