still trying to figure things out...
This commit is contained in:
parent
f92c2040d8
commit
675dddbc0a
@ -49,6 +49,8 @@ namespace Mocha.Core
|
||||
private NanoId _ID;
|
||||
private bool isNotEmpty;
|
||||
|
||||
public Guid GlobalIdentifier;
|
||||
|
||||
public InstanceHandle GetHandle() { return this; }
|
||||
|
||||
public static InstanceHandle Create()
|
||||
|
||||
47
mocha-dotnet/src/lib/Mocha.Core/InstanceReference.cs
Normal file
47
mocha-dotnet/src/lib/Mocha.Core/InstanceReference.cs
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||
//
|
||||
// This file is part of Mocha.NET.
|
||||
//
|
||||
// Mocha.NET is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Mocha.NET is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
public class InstanceReference
|
||||
{
|
||||
public InstanceReference(Guid globalIdentifier)
|
||||
{
|
||||
GlobalIdentifier = globalIdentifier;
|
||||
}
|
||||
public Guid GlobalIdentifier { get; }
|
||||
|
||||
public static bool operator==(InstanceReference left, InstanceReference right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
public static bool operator!=(InstanceReference left, InstanceReference right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is InstanceReference)
|
||||
{
|
||||
return ((InstanceReference)obj).GlobalIdentifier.Equals(this.GlobalIdentifier);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return GlobalIdentifier.GetHashCode();
|
||||
}
|
||||
}
|
||||
@ -266,6 +266,7 @@ public abstract class Oms
|
||||
{
|
||||
if (TryGetInstance(globalIdentifier, out InstanceHandle ih))
|
||||
{
|
||||
ih.GlobalIdentifier = globalIdentifier;
|
||||
return ih;
|
||||
}
|
||||
throw new KeyNotFoundException(String.Format("inst not found: {0}", globalIdentifier));
|
||||
@ -1212,7 +1213,7 @@ public abstract class Oms
|
||||
// to do its second pass "linking" the objects
|
||||
lib.Link();
|
||||
|
||||
InitializeLibraryInternal(lh, lib);
|
||||
InitializeLibrary(lh, lib);
|
||||
|
||||
return lh;
|
||||
}
|
||||
@ -1270,7 +1271,7 @@ public abstract class Oms
|
||||
// to do its second pass "linking" the objects
|
||||
lib.Link();
|
||||
|
||||
InitializeLibraryInternal(lh, lib);
|
||||
InitializeLibrary(lh, lib);
|
||||
|
||||
return lh;
|
||||
}
|
||||
@ -1284,12 +1285,17 @@ public abstract class Oms
|
||||
{
|
||||
LibraryHandle lh = LoadLibrary(st);
|
||||
_libraryFileNames[lh] = manifestResourceStreamName;
|
||||
_libraries[manifestResourceStreamName] = lh;
|
||||
return lh;
|
||||
}
|
||||
throw new KeyNotFoundException(String.Format("manifest resource stream named '{0}' not found", manifestResourceStreamName));
|
||||
}
|
||||
|
||||
protected abstract void InitializeLibraryInternal(LibraryHandle lh, Library lib);
|
||||
private void InitializeLibrary(LibraryHandle lh, Library lib)
|
||||
{
|
||||
InitializeLibraryInternal(lh, lib);
|
||||
}
|
||||
|
||||
public string? GetTenantName(TenantHandle tenant)
|
||||
{
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
|
||||
//
|
||||
// This file is part of Mocha.NET.
|
||||
//
|
||||
// Mocha.NET is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Mocha.NET is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using Mocha.Core.OmsImplementations;
|
||||
|
||||
namespace Mocha.Core.OmsImplementations;
|
||||
|
||||
public class EmbeddedMiniOms : MemoryOms
|
||||
{
|
||||
public string SystemLibraryResourceName { get; set; } = "Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl";
|
||||
|
||||
protected override void InitializeInternal()
|
||||
{
|
||||
base.InitializeInternal();
|
||||
|
||||
TenantHandle th = CreateTenant("super");
|
||||
SelectTenant(th);
|
||||
if (SystemLibraryResourceName != null)
|
||||
{
|
||||
LibraryHandle lh = LoadLibrary(typeof(EmbeddedMiniOms), SystemLibraryResourceName);
|
||||
AddLibraryReference(lh);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -25,6 +25,12 @@ public class MemoryOms : Oms
|
||||
{
|
||||
private class _Tenant
|
||||
{
|
||||
private MemoryOms oms;
|
||||
public _Tenant(MemoryOms oms)
|
||||
{
|
||||
this.oms = oms;
|
||||
}
|
||||
|
||||
private Dictionary<Guid, InstanceHandle> _instancesByGuid = new Dictionary<Guid, InstanceHandle>();
|
||||
private Dictionary<InstanceHandle, Guid> _guidsByInstance = new Dictionary<InstanceHandle, Guid>();
|
||||
|
||||
@ -43,6 +49,12 @@ public class MemoryOms : Oms
|
||||
{
|
||||
return _guidsByInstance[instance];
|
||||
}
|
||||
foreach (LibraryHandle lh in _libraryReferences)
|
||||
{
|
||||
Guid gid = oms._libraries[lh].GetGlobalIdentifier(instance);
|
||||
if (gid != Guid.Empty)
|
||||
return gid;
|
||||
}
|
||||
return Guid.Empty;
|
||||
}
|
||||
public InstanceKey GetInstanceKey(InstanceHandle instance)
|
||||
@ -61,6 +73,20 @@ public class MemoryOms : Oms
|
||||
ih = _instancesByGuid[globalIdentifier];
|
||||
return true;
|
||||
}
|
||||
foreach (LibraryHandle lh in _libraryReferences)
|
||||
{
|
||||
if (oms._libraries.ContainsKey(lh))
|
||||
{
|
||||
if (oms._libraries[lh].TryGetInstance(globalIdentifier, out ih))
|
||||
{
|
||||
// LibraryInst_g g = new LibraryInst_g() { InstanceHandle = ih, SourceLibrary = lh, GlobalIdentifier = globalIdentifier };
|
||||
// _libraries[lh]._libraryInst_gs[globalIdentifier] = g;
|
||||
// _libraries[lh]._libraryInst_is[ih] = g;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ih = InstanceHandle.Empty;
|
||||
return false;
|
||||
}
|
||||
@ -84,6 +110,8 @@ public class MemoryOms : Oms
|
||||
public InstanceHandle CreateInstance(Guid guid)
|
||||
{
|
||||
InstanceHandle ir = InstanceHandle.Create();
|
||||
ir.GlobalIdentifier = guid;
|
||||
|
||||
_instancesByGuid[guid] = ir;
|
||||
_guidsByInstance[ir] = guid;
|
||||
return ir;
|
||||
@ -139,6 +167,18 @@ public class MemoryOms : Oms
|
||||
return list2.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (LibraryHandle lh in _libraryReferences)
|
||||
{
|
||||
if (oms._libraries.ContainsKey(lh))
|
||||
{
|
||||
IReadOnlyCollection<InstanceHandle> insts2 = oms._libraries[lh].GetRelatedInstances(source, relationship, effectiveDate);
|
||||
if (insts2.Count > 0)
|
||||
{
|
||||
return insts2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new InstanceHandle[0];
|
||||
}
|
||||
|
||||
@ -161,7 +201,7 @@ public class MemoryOms : Oms
|
||||
return false;
|
||||
}
|
||||
|
||||
public object GetAttributeValue(InstanceHandle source, InstanceHandle attribute, DateTime effectiveDate)
|
||||
public object? GetAttributeValue(InstanceHandle source, InstanceHandle attribute, DateTime effectiveDate)
|
||||
{
|
||||
if (_Attributes.ContainsKey(source))
|
||||
{
|
||||
@ -182,6 +222,18 @@ public class MemoryOms : Oms
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (LibraryHandle lh in _libraryReferences)
|
||||
{
|
||||
if (oms._libraries.ContainsKey(lh))
|
||||
{
|
||||
object? value = oms._libraries[lh].GetAttributeValue(source, attribute, effectiveDate);
|
||||
if (value != null)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void SetAttributeValue(InstanceHandle source, InstanceHandle attribute, object value, DateTime effectiveDate)
|
||||
@ -203,6 +255,22 @@ public class MemoryOms : Oms
|
||||
}
|
||||
list.Add(new AttributeValue(effectiveDate, value));
|
||||
}
|
||||
|
||||
private List<LibraryHandle> _libraryReferences = new List<LibraryHandle>();
|
||||
|
||||
public void AddLibraryReference(LibraryHandle library)
|
||||
{
|
||||
if (!_libraryReferences.Contains(library))
|
||||
{
|
||||
// please don't reference the same library multiple times
|
||||
_libraryReferences.Add(library);
|
||||
}
|
||||
}
|
||||
public void RemoveLibraryReference(LibraryHandle library)
|
||||
{
|
||||
if (_libraryReferences.Contains(library))
|
||||
_libraryReferences.Remove(library);
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<TenantHandle, _Tenant> _tenantData = new Dictionary<TenantHandle, _Tenant>();
|
||||
@ -215,7 +283,7 @@ public class MemoryOms : Oms
|
||||
protected override TenantHandle CreateTenantInternal(string tenantName)
|
||||
{
|
||||
TenantHandle th = TenantHandle.Create();
|
||||
_tenantData[th] = new _Tenant();
|
||||
_tenantData[th] = new _Tenant(this);
|
||||
return th;
|
||||
}
|
||||
protected override bool SelectTenantInternal(TenantHandle tenant)
|
||||
@ -229,29 +297,24 @@ public class MemoryOms : Oms
|
||||
_CurrentTenantData = null;
|
||||
}
|
||||
|
||||
private Dictionary<TenantHandle, List<LibraryHandle>> _libraryReferences = new Dictionary<TenantHandle, List<LibraryHandle>>();
|
||||
|
||||
protected override void AddLibraryReferenceInternal(LibraryHandle library)
|
||||
{
|
||||
if (!_libraryReferences.ContainsKey(_CurrentTenant))
|
||||
if (_CurrentTenantData != null)
|
||||
{
|
||||
_libraryReferences[_CurrentTenant] = new List<LibraryHandle>();
|
||||
}
|
||||
if (!_libraryReferences[_CurrentTenant].Contains(library))
|
||||
{
|
||||
// please don't reference the same library multiple times
|
||||
_libraryReferences[_CurrentTenant].Add(library);
|
||||
_CurrentTenantData.AddLibraryReference(library);
|
||||
}
|
||||
}
|
||||
protected override void RemoveLibraryReferenceInternal(LibraryHandle library)
|
||||
{
|
||||
if (_libraryReferences.ContainsKey(_CurrentTenant))
|
||||
if (_CurrentTenantData != null)
|
||||
{
|
||||
if (_libraryReferences[_CurrentTenant].Contains(library))
|
||||
{
|
||||
_libraryReferences[_CurrentTenant].Remove(library);
|
||||
_CurrentTenantData.RemoveLibraryReference(library);
|
||||
}
|
||||
}
|
||||
|
||||
public void __Test_AddLibraryReference_1(LibraryHandle lhWeb, LibraryHandle lhSystem)
|
||||
{
|
||||
_libraries[lhWeb].AddLibraryReference(lhSystem);
|
||||
}
|
||||
|
||||
protected override Guid GetGlobalIdentifierInternal(InstanceHandle instance)
|
||||
@ -260,22 +323,6 @@ public class MemoryOms : Oms
|
||||
throw new InvalidOperationException("Please select a tenant first.");
|
||||
|
||||
Guid gid = _CurrentTenantData.GetGlobalIdentifier(instance);
|
||||
if (gid == Guid.Empty)
|
||||
{
|
||||
if (_libraryReferences.ContainsKey(_CurrentTenant))
|
||||
{
|
||||
foreach (LibraryHandle lh in _libraryReferences[_CurrentTenant])
|
||||
{
|
||||
gid = _libraries[lh].GetGlobalIdentifier(instance);
|
||||
if (gid != Guid.Empty)
|
||||
return gid;
|
||||
}
|
||||
}
|
||||
// if (_libraryInst_is.ContainsKey(instance))
|
||||
// {
|
||||
// gid = _libraryInst_is[instance].GlobalIdentifier;
|
||||
// }
|
||||
}
|
||||
return gid;
|
||||
}
|
||||
protected override InstanceKey GetInstanceKeyInternal(InstanceHandle instance)
|
||||
@ -315,7 +362,7 @@ public class MemoryOms : Oms
|
||||
|
||||
protected override void InitializeLibraryInternal(LibraryHandle lh, Library data)
|
||||
{
|
||||
_Tenant lib = new _Tenant();
|
||||
_Tenant lib = new _Tenant(this);
|
||||
foreach (LibraryInstance inst in data.Instances)
|
||||
{
|
||||
InstanceHandle ih = lib.CreateInstance(inst.InstanceGuid);
|
||||
@ -357,33 +404,6 @@ public class MemoryOms : Oms
|
||||
throw new InvalidOperationException("Please select a tenant first.");
|
||||
|
||||
bool v = _CurrentTenantData.TryGetInstance(globalIdentifier, out ih);
|
||||
if (!v)
|
||||
{
|
||||
// if (_libraryInst_gs.ContainsKey(globalIdentifier))
|
||||
// {
|
||||
// ih = _libraryInst_gs[globalIdentifier].InstanceHandle;
|
||||
// return true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
if (_libraryReferences.ContainsKey(_CurrentTenant))
|
||||
{
|
||||
foreach (LibraryHandle lh in _libraryReferences[_CurrentTenant])
|
||||
{
|
||||
if (_libraries.ContainsKey(lh))
|
||||
{
|
||||
if (_libraries[lh].TryGetInstance(globalIdentifier, out ih))
|
||||
{
|
||||
// LibraryInst_g g = new LibraryInst_g() { InstanceHandle = ih, SourceLibrary = lh, GlobalIdentifier = globalIdentifier };
|
||||
// _libraries[lh]._libraryInst_gs[globalIdentifier] = g;
|
||||
// _libraries[lh]._libraryInst_is[ih] = g;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
return v;
|
||||
}
|
||||
protected override bool TryGetInstanceInternal(InstanceKey ik, out InstanceHandle ih)
|
||||
@ -432,20 +452,6 @@ public class MemoryOms : Oms
|
||||
throw new InvalidOperationException("Please select a tenant first.");
|
||||
|
||||
IReadOnlyCollection<InstanceHandle> insts = _CurrentTenantData.GetRelatedInstances(source, relationship, effectiveDate);
|
||||
if (insts.Count == 0)
|
||||
{
|
||||
foreach (LibraryHandle lh in _libraryReferences[_CurrentTenant])
|
||||
{
|
||||
if (_libraries.ContainsKey(lh))
|
||||
{
|
||||
IReadOnlyCollection<InstanceHandle> insts2 = _libraries[lh].GetRelatedInstances(source, relationship, effectiveDate);
|
||||
if (insts2.Count > 0)
|
||||
{
|
||||
return insts2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return insts;
|
||||
}
|
||||
|
||||
@ -462,20 +468,6 @@ public class MemoryOms : Oms
|
||||
throw new InvalidOperationException("Please select a tenant first.");
|
||||
|
||||
object value = _CurrentTenantData.GetAttributeValue(source, attribute, effectiveDate);
|
||||
if (value == null)
|
||||
{
|
||||
foreach (LibraryHandle lh in _libraryReferences[_CurrentTenant])
|
||||
{
|
||||
if (_libraries.ContainsKey(lh))
|
||||
{
|
||||
value = _libraries[lh].GetAttributeValue(source, attribute, effectiveDate);
|
||||
if (value != null)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
protected override void SetAttributeValueInternal(InstanceHandle source, InstanceHandle attribute, object value, DateTime effectiveDate)
|
||||
|
||||
@ -26,7 +26,7 @@ using MBS.Core;
|
||||
/// </summary>
|
||||
public class HardcodedMiniOms : MemoryOms
|
||||
{
|
||||
private HardcodedMiniOms()
|
||||
public HardcodedMiniOms()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@ -4,14 +4,18 @@ namespace Mocha.Core.Tests;
|
||||
|
||||
public class EmbeddedMiniOms : MemoryOms
|
||||
{
|
||||
public string? SystemLibraryResourceName { get; set; } = "Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl";
|
||||
|
||||
protected override void InitializeInternal()
|
||||
{
|
||||
base.InitializeInternal();
|
||||
|
||||
LibraryHandle lh = LoadLibrary(typeof(EmbeddedMiniOms), "Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl");
|
||||
|
||||
TenantHandle th = CreateTenant("super");
|
||||
SelectTenant(th);
|
||||
if (SystemLibraryResourceName != null)
|
||||
{
|
||||
LibraryHandle lh = LoadLibrary(typeof(EmbeddedMiniOms), SystemLibraryResourceName);
|
||||
AddLibraryReference(lh);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,7 @@
|
||||
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using Mocha.Core.OmsImplementations;
|
||||
using Mocha.Core.OmsImplementations.Mini;
|
||||
|
||||
namespace Mocha.Core.Tests;
|
||||
@ -31,8 +31,12 @@ public class LibraryLoaderTests : OmsTestsBase
|
||||
base.AfterSetup();
|
||||
|
||||
// add a reference to the other library
|
||||
LibraryHandle lhSystem = Oms.GetLibrary("Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl");
|
||||
|
||||
lhWeb = Oms.LoadLibrary(typeof(LibraryLoaderTests), "Mocha.Core.Tests.Resources.net.alcetech.Mocha.Web.mcl");
|
||||
Oms.AddLibraryReference(lhWeb);
|
||||
|
||||
((MemoryOms)Oms).__Test_AddLibraryReference_1(lhWeb, lhSystem);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -67,6 +71,11 @@ public class LibraryLoaderTests : OmsTestsBase
|
||||
[Test]
|
||||
public void Parent_Class_referenced_from_One_library_Accessible_from_Another()
|
||||
{
|
||||
//! THIS WON'T WORK BECAUSE...
|
||||
//! Parent Class referenced from another library requires a LibraryReference to the other library on the current library
|
||||
//! BUT... there is no way right now to represent that in _Tenant
|
||||
//! FIXME: add LibraryReferences to _Tenant and fix GetRelatedInstances etc. so that libraries can reference other libraries
|
||||
|
||||
// First we make sure that Class (defined in Mocha.System, which we are known to have) loads
|
||||
InstanceHandle ihClass = Oms.GetInstance(KnownInstanceGuids.Classes.Class);
|
||||
Assert.That(ihClass, Is.Not.EqualTo(InstanceHandle.Empty));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user