Creating an unowned CmPossibilityList issues no PropChanged
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 3
- Forks
- 16
- Avg merge
- 22h 40m
- Merged PRs (30d)
- 1
Description
Gap
IUnitOfWorkService.RegisterObjectAsCreated (src/SIL.LCModel/Infrastructure/Impl/UnitOfWorkService.cs:583) records creation as an LcmStateChangeObjectCreation (src/SIL.LCModel/Infrastructure/Impl/LcmStateChangingClasses.cs:279). That class derives from LcmStateChangeBase and does not implement ILcmPropertyChanged. UnitOfWork.GetPropChangeInformation (src/SIL.LCModel/Infrastructure/Impl/UnitOfWork.cs:621) yields only from actions that implement ILcmPropertyChanged, so object creation by itself produces no ChangeInformation.
For an owned object the PropChanged arrives from the owning property's LcmVectorPropertyChanged / LcmAtomicRefPropertyChanged. An unowned object has no owning property, so no IVwNotifyChange.PropChanged is issued at all. This is the open TODO at UnitOfWorkService.cs:599:
// (TODO: What needs to be done for unowned objects?)
ICmPossibilityListFactory.CreateUnowned (src/SIL.LCModel/DomainImpl/FactoryAdditions.cs:1560) hits this. The new CmPossibilityList is registered in the IdentityMap, is returned by ICmPossibilityListRepository.AllInstances(), and is persisted as a UOW newbie — but no client receives a PropChanged, so nothing that caches a view of the lists is told to reload.
Proposed fix
Apply the pattern already used for the other unowned classes:
LexEntry.RegisterVirtualsModifiedForObjectCreation(src/SIL.LCModel/DomainImpl/OverridesLing_Lex.cs:854) →Virtuals.LexDbEntriesText.RegisterVirtualsModifiedForObjectCreation/...ForObjectDeletion(src/SIL.LCModel/DomainImpl/OverridesLing_Wfi.cs:1713and:1746) →Virtuals.LangProjTexts
-
Add a
Virtualsaccessor forLangProject.AllPossibilityLists, which already exists as a virtual property (src/SIL.LCModel/DomainImpl/OverridesLangProj.cs:83, declared[VirtualProperty(CellarPropertyType.ReferenceCollection, "CmPossibilityList")]). Model it onVirtuals.LangProjTexts(src/SIL.LCModel/DomainImpl/Virtuals.cs:205). -
On
CmPossibilityList, overrideRegisterVirtualsModifiedForObjectCreationandRegisterVirtualsModifiedForObjectDeletion(src/SIL.LCModel/DomainImpl/CmObject.cs:1758and:1769) to calluow.RegisterVirtualCollectionAsModifiedfor that flid onCache.LangProject, and invoke them fromSetDefaultValuesAfterInit/OnBeforeObjectDeletedthe wayTextdoes. -
Make
CmPossibilityListFactory.CreateUnownedcall((ICmObjectInternal)result).InitializeNewOwnerlessCmObjectWithPresetGuid()before returning, matching the generated ownerlessCmPossibilityListFactory.Create(Guid)(src/SIL.LCModel/DomainImpl/GeneratedFactoryImplementations.cs:320-327). Without this,SetDefaultValuesAfterInitnever runs on theCreateUnownedpath and the hook added in step 2 would not fire.
ChangeReconciler.ReconcileForeignChanges already calls RegisterVirtualsModifiedForObjectCreation on each foreign newby (src/SIL.LCModel/Infrastructure/Impl/ChangeReconciler.cs:212), so step 2 also covers Send/Receive and second-window reconciliation.
Note that SetDefaultValuesAfterInit also runs during bootstrap and data migration, where Cache.LangProject may not be resolvable; LexEntry and Text carry the same exposure, so follow whatever guard they rely on.
Out of scope
Custom field metadata is a separate mechanism with no notification path at all: LcmMetaDataCache.AddCustomField / UpdateCustomField / DeleteCustomField mutate m_metaFieldRecords in place, and FieldDescription.UpdateCustomField registers affected objects as modified but registers no metadata change. Clients must continue to be notified manually after adding a custom field.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with UnitOfWorkService.cs, Virtuals.cs, CmObject.cs, and FactoryAdditions.cs, comparing the LexEntry and Text virtual-notification implementations with the CreateUnowned path. Trace SetDefaultValuesAfterInit and OnBeforeObjectDeleted, including bootstrap guards, then verify that creating or deleting an unowned CmPossibilityList produces the expected PropChanged notification and that the ownerless factory initialization path is used.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100