From 529896cdefe6e1be69790384d1283c91258a3bfb Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Fri, 18 Oct 2024 13:45:49 +0700 Subject: [PATCH 1/4] expose data reader via Cache.InternalServices.DataReader --- src/SIL.LCModel/ILcmServiceLocator.cs | 1 + src/SIL.LCModel/IOC/LcmServiceLocatorFactory.cs | 8 ++++++++ src/SIL.LCModel/LcmCache.cs | 5 +++++ 3 files changed, 14 insertions(+) diff --git a/src/SIL.LCModel/ILcmServiceLocator.cs b/src/SIL.LCModel/ILcmServiceLocator.cs index 7f500c64..9d37345d 100644 --- a/src/SIL.LCModel/ILcmServiceLocator.cs +++ b/src/SIL.LCModel/ILcmServiceLocator.cs @@ -96,6 +96,7 @@ internal interface IServiceLocatorInternal IdentityMap IdentityMap { get; } LoadingServices LoadingServices { get; } IUnitOfWorkService UnitOfWorkService { get; } + IDataReader DataReader { get; } } /// diff --git a/src/SIL.LCModel/IOC/LcmServiceLocatorFactory.cs b/src/SIL.LCModel/IOC/LcmServiceLocatorFactory.cs index 97a61a27..f04fa79e 100644 --- a/src/SIL.LCModel/IOC/LcmServiceLocatorFactory.cs +++ b/src/SIL.LCModel/IOC/LcmServiceLocatorFactory.cs @@ -430,6 +430,14 @@ public IDataSetup DataSetup } } + public IDataReader DataReader + { + get + { + return GetInstance(); + } + } + /// /// Get the specified object instance; short for getting ICmObjectRepository and asking it to GetObject. /// diff --git a/src/SIL.LCModel/LcmCache.cs b/src/SIL.LCModel/LcmCache.cs index 7a427718..b6ed78d3 100644 --- a/src/SIL.LCModel/LcmCache.cs +++ b/src/SIL.LCModel/LcmCache.cs @@ -1085,6 +1085,11 @@ public ILcmServiceLocator ServiceLocator get { return m_serviceLocator; } } + internal IServiceLocatorInternal InternalServices + { + get { return (IServiceLocatorInternal) m_serviceLocator; } + } + /// /// Add to the list a ClassAndPropInfo for each concrete class of object that may be added to /// property flid. From f620cf41e54f82969fa49f1d1aab17a58ca5b3d8 Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Fri, 18 Oct 2024 13:48:26 +0700 Subject: [PATCH 2/4] declare new method ILcmFactory.Create(Guid guid) implement via code generation remove ICmPicture Create method --- .../DomainImpl/FactoryAdditions.cs | 14 ------------- src/SIL.LCModel/FactoryInterfaceAdditions.cs | 5 ----- src/SIL.LCModel/InterfaceDeclarations.cs | 6 ++++++ src/SIL.LCModel/LcmGenerate/factory.vm.cs | 20 +++++++++++++++++++ 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/SIL.LCModel/DomainImpl/FactoryAdditions.cs b/src/SIL.LCModel/DomainImpl/FactoryAdditions.cs index 06482d00..11254e1b 100644 --- a/src/SIL.LCModel/DomainImpl/FactoryAdditions.cs +++ b/src/SIL.LCModel/DomainImpl/FactoryAdditions.cs @@ -2137,20 +2137,6 @@ private static void ParsePictureLoc(string s, ref PictureLocationRangeType locTy return; } } - - /// - /// Create a new entry with the given guid. - /// - public ICmPicture Create(Guid guid) - { - if (guid == Guid.Empty) - return Create(); - - int hvo = ((IDataReader) m_cache.ServiceLocator.GetInstance()) - .GetNextRealHvo(); - return new CmPicture(m_cache, hvo, guid); - } - } #endregion diff --git a/src/SIL.LCModel/FactoryInterfaceAdditions.cs b/src/SIL.LCModel/FactoryInterfaceAdditions.cs index 8c17ef97..7b55a56e 100644 --- a/src/SIL.LCModel/FactoryInterfaceAdditions.cs +++ b/src/SIL.LCModel/FactoryInterfaceAdditions.cs @@ -845,11 +845,6 @@ ICmPicture Create(string sFolder, int anchorLoc, IPictureLocationBridge location ICmPicture Create(string sFolder, int anchorLoc, IPictureLocationBridge locationParser, string sDescription, string srcFilename, string sLayoutPos, string sLocationRange, string sCopyright, string sCaption, PictureLocationRangeType locRangeType, string sScaleFactor); - - /// - /// Create a new entry with the given guid. - /// - ICmPicture Create(Guid guid); } /// diff --git a/src/SIL.LCModel/InterfaceDeclarations.cs b/src/SIL.LCModel/InterfaceDeclarations.cs index 2ab68ecc..d974b172 100644 --- a/src/SIL.LCModel/InterfaceDeclarations.cs +++ b/src/SIL.LCModel/InterfaceDeclarations.cs @@ -638,6 +638,12 @@ public interface ILcmFactory where T : ICmObject /// /// A new, unowned, ICmObject with a Guid, but no Hvo. T Create(); + + /// + /// Basic creation method for an ICmObject with the given guid. + /// + /// A new, unowned, ICmObject with the given guid. + T Create(Guid guid); } #endregion diff --git a/src/SIL.LCModel/LcmGenerate/factory.vm.cs b/src/SIL.LCModel/LcmGenerate/factory.vm.cs index 3e6af2cb..8e684c90 100644 --- a/src/SIL.LCModel/LcmGenerate/factory.vm.cs +++ b/src/SIL.LCModel/LcmGenerate/factory.vm.cs @@ -10,6 +10,7 @@ ## -------------------------------------------------------------------------------------------- #set( $className = $class.Name ) #set( $baseClassName = $class.BaseClass.Name ) +#set( $ownerStatus = $class.OwnerStatus ) #if ($class.Name == "LgWritingSystem") #set( $classSfx = "FactoryLcm" ) #else @@ -52,6 +53,25 @@ internal partial class ${className}$classSfx : I${className}$classSfx, ILcmFacto ((ICmObjectInternal)newby).InitializeNewOwnerlessCmObject(m_cache); return newby; } + + /// + /// Basic creation method for an $className. + /// + /// A new, unowned, $className with the given guid. + public I$className Create(Guid guid) + { +#if ($class.IsSingleton) + if (m_cache.ServiceLocator.GetInstance().Singleton != null) + throw new InvalidOperationException("Can not create more than one ${className}"); +#end + if (guid == Guid.Empty) throw new ArgumentException("Can not create a new ${className} with an empty guid."); + int hvo = m_cache.InternalServices.DataReader.GetNextRealHvo(); + var newby = new $className(m_cache, hvo, guid); +#if ( $ownerStatus != "required") + ((ICmObjectInternal) newby).InitializeNewOwnerlessCmObjectWithPresetGuid(); +#end + return newby; + } #end /// From e1987f4fff0d9152fe76bf9c630d64bcce2236a1 Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Fri, 18 Oct 2024 14:57:50 +0700 Subject: [PATCH 3/4] change behavior when guid is empty --- src/SIL.LCModel/LcmGenerate/factory.vm.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SIL.LCModel/LcmGenerate/factory.vm.cs b/src/SIL.LCModel/LcmGenerate/factory.vm.cs index 8e684c90..21639ae4 100644 --- a/src/SIL.LCModel/LcmGenerate/factory.vm.cs +++ b/src/SIL.LCModel/LcmGenerate/factory.vm.cs @@ -64,7 +64,7 @@ internal partial class ${className}$classSfx : I${className}$classSfx, ILcmFacto if (m_cache.ServiceLocator.GetInstance().Singleton != null) throw new InvalidOperationException("Can not create more than one ${className}"); #end - if (guid == Guid.Empty) throw new ArgumentException("Can not create a new ${className} with an empty guid."); + if (guid == Guid.Empty) guid = Guid.NewGuid(); int hvo = m_cache.InternalServices.DataReader.GetNextRealHvo(); var newby = new $className(m_cache, hvo, guid); #if ( $ownerStatus != "required") From fc2d984931fc977c71c906c5bd4c9af900aa3492 Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Fri, 18 Oct 2024 15:23:32 +0700 Subject: [PATCH 4/4] add a test ensuring LexEntryTypes can be created with a guid --- .../Infrastructure/Impl/LexEntryTypeTests.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/SIL.LCModel.Tests/Infrastructure/Impl/LexEntryTypeTests.cs diff --git a/tests/SIL.LCModel.Tests/Infrastructure/Impl/LexEntryTypeTests.cs b/tests/SIL.LCModel.Tests/Infrastructure/Impl/LexEntryTypeTests.cs new file mode 100644 index 00000000..753bf3bf --- /dev/null +++ b/tests/SIL.LCModel.Tests/Infrastructure/Impl/LexEntryTypeTests.cs @@ -0,0 +1,20 @@ +using System; +using System.Linq; +using NUnit.Framework; + +namespace SIL.LCModel.Infrastructure.Impl +{ + public class LexEntryTypeTests: MemoryOnlyBackendProviderRestoredForEachTestTestBase + { + [Test] + public void CreateTypeWithGuid_CanAddToList() + { + var guid = Guid.NewGuid(); + var lexEntryType = Cache.ServiceLocator.GetInstance().Create(guid); + + Cache.LangProject.LexDbOA.ComplexEntryTypesOA.PossibilitiesOS.Add(lexEntryType); + + Assert.That(Cache.ServiceLocator.ObjectRepository.GetObject(guid), Is.EqualTo(lexEntryType)); + } + } +} \ No newline at end of file