sillsdev / sillsdev/liblcm

Creating an unowned CmPossibilityList issues no PropChanged

Open
#397 0 comments 0 reactions 0 assignees View on GitHub

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.LexDbEntries
  • Text.RegisterVirtualsModifiedForObjectCreation / ...ForObjectDeletion (src/SIL.LCModel/DomainImpl/OverridesLing_Wfi.cs:1713 and :1746) → Virtuals.LangProjTexts
  1. Add a Virtuals accessor for LangProject.AllPossibilityLists, which already exists as a virtual property (src/SIL.LCModel/DomainImpl/OverridesLangProj.cs:83, declared [VirtualProperty(CellarPropertyType.ReferenceCollection, "CmPossibilityList")]). Model it on Virtuals.LangProjTexts (src/SIL.LCModel/DomainImpl/Virtuals.cs:205).

  2. On CmPossibilityList, override RegisterVirtualsModifiedForObjectCreation and RegisterVirtualsModifiedForObjectDeletion (src/SIL.LCModel/DomainImpl/CmObject.cs:1758 and :1769) to call uow.RegisterVirtualCollectionAsModified for that flid on Cache.LangProject, and invoke them from SetDefaultValuesAfterInit / OnBeforeObjectDeleted the way Text does.

  3. Make CmPossibilityListFactory.CreateUnowned call ((ICmObjectInternal)result).InitializeNewOwnerlessCmObjectWithPresetGuid() before returning, matching the generated ownerless CmPossibilityListFactory.Create(Guid) (src/SIL.LCModel/DomainImpl/GeneratedFactoryImplementations.cs:320-327). Without this, SetDefaultValuesAfterInit never runs on the CreateUnowned path 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.