diff --git a/src/SIL.LCModel/LcmGenerate/factory.vm.cs b/src/SIL.LCModel/LcmGenerate/factory.vm.cs index 21639ae4..f169d1d5 100644 --- a/src/SIL.LCModel/LcmGenerate/factory.vm.cs +++ b/src/SIL.LCModel/LcmGenerate/factory.vm.cs @@ -64,7 +64,19 @@ 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) guid = Guid.NewGuid(); + if (guid == Guid.Empty) + { + guid = Guid.NewGuid(); + } + else + { + if (m_cache.ServiceLocator.GetInstance().IsValidObjectId(guid)) + { + // IsValidObjectId returns true if the GUID exists, i.e. you could call GetObject and get something. + // But here in Create(), it's an error if the GUID already exists: duplicate GUIDs are not allowed. + throw new InvalidOperationException("Can not create more than one object with identical GUIDs"); + } + } int hvo = m_cache.InternalServices.DataReader.GetNextRealHvo(); var newby = new $className(m_cache, hvo, guid); #if ( $ownerStatus != "required") diff --git a/tests/SIL.LCModel.Tests/DomainImpl/FactoryAdditionsTests.cs b/tests/SIL.LCModel.Tests/DomainImpl/FactoryAdditionsTests.cs index 0a6edac1..22ab710b 100644 --- a/tests/SIL.LCModel.Tests/DomainImpl/FactoryAdditionsTests.cs +++ b/tests/SIL.LCModel.Tests/DomainImpl/FactoryAdditionsTests.cs @@ -1,7 +1,8 @@ -// Copyright (c) 2015 SIL International +// Copyright (c) 2015 SIL International // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) +using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -132,5 +133,28 @@ public void LexSenseFactoryCreate_NullGlossTss_DoesNotThrow() Assert.DoesNotThrow(() => sense = lexSenseFactory.Create(entry, msa, nullGloss)); Assert.AreEqual(0, sense.Gloss.StringCount); } + + [Test] + public void Create_WithDuplicateGuid_SameType_Throws() + { + var guid = Guid.NewGuid(); + var factory = Cache.ServiceLocator.GetInstance(); + factory.Create(guid); + + Assert.That(() => factory.Create(guid), + Throws.TypeOf().With.Message.Contains("identical GUIDs")); + } + + [Test] + public void Create_WithDuplicateGuid_DifferentType_Throws() + { + var guid = Guid.NewGuid(); + var entryFactory = Cache.ServiceLocator.GetInstance(); + entryFactory.Create(guid); + + var pictureFactory = Cache.ServiceLocator.GetInstance(); + Assert.That(() => pictureFactory.Create(guid), + Throws.TypeOf().With.Message.Contains("identical GUIDs")); + } } }