Skip to content

Commit

Permalink
Add T Create(Guid) to ILcmFactory<T> (#313)
Browse files Browse the repository at this point in the history
* expose data reader via Cache.InternalServices.DataReader

* declare new method ILcmFactory<T>.Create(Guid guid)
 implement via code generation
 remove ICmPicture Create method

* change behavior when guid is empty

* add a test ensuring LexEntryTypes can be created with a guid

---------

Co-authored-by: Jake Oliver <jeoliver97@gmail.com>
  • Loading branch information
hahn-kev and JakeOliver28 authored Nov 2, 2024
1 parent 80c9d96 commit 2820554
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 19 deletions.
14 changes: 0 additions & 14 deletions src/SIL.LCModel/DomainImpl/FactoryAdditions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2137,20 +2137,6 @@ private static void ParsePictureLoc(string s, ref PictureLocationRangeType locTy
return;
}
}

/// <summary>
/// Create a new entry with the given guid.
/// </summary>
public ICmPicture Create(Guid guid)
{
if (guid == Guid.Empty)
return Create();

int hvo = ((IDataReader) m_cache.ServiceLocator.GetInstance<IDataSetup>())
.GetNextRealHvo();
return new CmPicture(m_cache, hvo, guid);
}

}
#endregion

Expand Down
5 changes: 0 additions & 5 deletions src/SIL.LCModel/FactoryInterfaceAdditions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/// <summary>
/// Create a new entry with the given guid.
/// </summary>
ICmPicture Create(Guid guid);
}

/// <summary>
Expand Down
1 change: 1 addition & 0 deletions src/SIL.LCModel/ILcmServiceLocator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ internal interface IServiceLocatorInternal
IdentityMap IdentityMap { get; }
LoadingServices LoadingServices { get; }
IUnitOfWorkService UnitOfWorkService { get; }
IDataReader DataReader { get; }
}

/// <summary>
Expand Down
8 changes: 8 additions & 0 deletions src/SIL.LCModel/IOC/LcmServiceLocatorFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,14 @@ public IDataSetup DataSetup
}
}

public IDataReader DataReader
{
get
{
return GetInstance<IDataReader>();
}
}

/// <summary>
/// Get the specified object instance; short for getting ICmObjectRepository and asking it to GetObject.
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions src/SIL.LCModel/InterfaceDeclarations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,12 @@ public interface ILcmFactory<T> where T : ICmObject
/// </summary>
/// <returns>A new, unowned, ICmObject with a Guid, but no Hvo.</returns>
T Create();

/// <summary>
/// Basic creation method for an ICmObject with the given guid.
/// </summary>
/// <returns>A new, unowned, ICmObject with the given guid.</returns>
T Create(Guid guid);
}
#endregion

Expand Down
5 changes: 5 additions & 0 deletions src/SIL.LCModel/LcmCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,11 @@ public ILcmServiceLocator ServiceLocator
get { return m_serviceLocator; }
}

internal IServiceLocatorInternal InternalServices
{
get { return (IServiceLocatorInternal) m_serviceLocator; }
}

/// <summary>
/// Add to the list a ClassAndPropInfo for each concrete class of object that may be added to
/// property flid.
Expand Down
20 changes: 20 additions & 0 deletions src/SIL.LCModel/LcmGenerate/factory.vm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -52,6 +53,25 @@ internal partial class ${className}$classSfx : I${className}$classSfx, ILcmFacto
((ICmObjectInternal)newby).InitializeNewOwnerlessCmObject(m_cache);
return newby;
}

/// <summary>
/// Basic creation method for an $className.
/// </summary>
/// <returns>A new, unowned, $className with the given guid.</returns>
public I$className Create(Guid guid)
{
#if ($class.IsSingleton)
if (m_cache.ServiceLocator.GetInstance<I${className}Repository>().Singleton != null)
throw new InvalidOperationException("Can not create more than one ${className}");
#end
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")
((ICmObjectInternal) newby).InitializeNewOwnerlessCmObjectWithPresetGuid();
#end
return newby;
}
#end

/// <summary>
Expand Down
20 changes: 20 additions & 0 deletions tests/SIL.LCModel.Tests/Infrastructure/Impl/LexEntryTypeTests.cs
Original file line number Diff line number Diff line change
@@ -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<ILexEntryTypeFactory>().Create(guid);

Cache.LangProject.LexDbOA.ComplexEntryTypesOA.PossibilitiesOS.Add(lexEntryType);

Assert.That(Cache.ServiceLocator.ObjectRepository.GetObject(guid), Is.EqualTo(lexEntryType));
}
}
}

0 comments on commit 2820554

Please sign in to comment.