Value Type Definition in-lining
The LLBLGen Pro designer supports Value Type Definitions (in the context of Domain Driven Design, e.g. Address), however the LLBLGen Pro Runtime Framework does not. To leverage the modeling advantages of Value Type Definitions in a model while still using the LLBLGen Pro Runtime Framework, the designer supports Value Type Definition in-lining. How this works is described below.
Overview
Say a valuetype AddressVT is defined with the fields Streetname, HouseNr, City, Zipcode and Country. There's also a valuetype ZipCodeVT which has one field: Value. There are two entities which have a field of type AddressVT: Customer and Employee. Customer.VisitingAddress is of type AddressVT and Employee.Address is of type AddressVT.
This makes model-first development in a model easier, as one can define the valuetypes for modeling purposes, define fields easier in both Customer and Employee.
Inlining, or flattening, the aforementioned valuetypes will result, into the following fields in Customer:
- Customer.VisitingAddressStreetName
- Customer.VisitingAddressHouseNr
- Customer.VisitingAddressCity
- Customer.VisitingAddressZipCodeValue
- Customer.VisitingAddressCountry
and the following fields in Employee:
- Employee.AddressStreetName
- Employee.AddressHouseNr
- Employee.AddressCity
- Employee.AddressZipCodeValue
- Employee.AddressCountry
Value type definition inlining is done by default.
Setting controlling inlining of value type definitions
The framework specific setting InlineValueTypedFields (default: true) will control whether the code generator will inline the valuetype fields as normal fields. When set to false, the validator will throw an error if the project has a valuetyped field like it did in v3.x versions.
Nullability
The inlined fields inherit their nullability from the IsOptional value of the Value Type Definition's fields. So in our example above, if AddressVT.Country is optional, the Customer.VisitingAddressCountry field is optional too. The IsOptional flag value of the ValueTyped field (in our example Customer.VisitingAddress, as it's of type AddressVT) is ignored.
Naming rule
The value which is used for constructing the name of the resultfield is obtained from the MappedFieldWrapper.PathAsStringForTargetFieldName property from the field mapping of the valuetype's field in the entity mapping itself. This isn't configurable. Using this name as the output name makes it predictable which field names the entity will get in code.