diff --git a/mocha-dotnet/src/lib/Mocha.Core/ClassImplementationRegistry.cs b/mocha-dotnet/src/lib/Mocha.Core/ClassImplementationRegistry.cs new file mode 100644 index 0000000..af97e28 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/ClassImplementationRegistry.cs @@ -0,0 +1,71 @@ +// Copyright (C) 2025 Michael Becker +// +// 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 . + +using Mocha.Core.Oop; + +namespace Mocha.Core; + +public class ClassImplementationRegistry +{ + private Dictionary implementations = new Dictionary(); + + public void Register(Guid methodClassId, T implementation) where T : ClassImplementation + { + implementations[methodClassId] = implementation; + } + + public bool Contains(Guid classGuid) + { + return implementations.ContainsKey(classGuid); + } + public bool Contains(Guid classGuid) where T : ClassImplementation + { + if (implementations.ContainsKey(classGuid)) + { + if (implementations[classGuid] is T) + { + return true; + } + } + return false; + } + + public T Get(Guid classGuid) where T : ClassImplementation + { + if (implementations.ContainsKey(classGuid)) + { + if (implementations[classGuid] is T obj) + { + return obj; + } + } + throw new NotImplementedException(String.Format("implementation for class {0} not found or incorrect type", classGuid)); + } + public bool TryGet(Guid classGuid, out T? implementation) where T : ClassImplementation + { + if (implementations.ContainsKey(classGuid)) + { + if (implementations[classGuid] is T obj) + { + implementation = obj; + return true; + } + } + implementation = null; + return false; + } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs index eb40733..2657f8c 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs @@ -55,13 +55,13 @@ public abstract class Oms MethodImplementation[] methodImplementations = MBS.Core.Reflection.TypeLoader.GetAvailableTypes(new System.Reflection.Assembly[] { Assembly.GetExecutingAssembly() }); foreach (MethodImplementation impl in methodImplementations) { - RegisterMethodImplementation(impl.ClassGuid, impl); + ClassImplementations.Register(impl.ClassGuid, impl); } AttributeImplementation[] attributeImplementations = MBS.Core.Reflection.TypeLoader.GetAvailableTypes(new System.Reflection.Assembly[] { Assembly.GetExecutingAssembly() }); foreach (AttributeImplementation impl in attributeImplementations) { - RegisterAttributeImplementation(impl.ClassGuid, impl); + ClassImplementations.Register(impl.ClassGuid, impl); } } @@ -1219,17 +1219,7 @@ public abstract class Oms return value; } - private Dictionary methodImplementations = new Dictionary(); - private void RegisterMethodImplementation(Guid methodClassId, MethodImplementation implementation) - { - methodImplementations[methodClassId] = implementation; - } - - private Dictionary attributeImplementations = new Dictionary(); - private void RegisterAttributeImplementation(Guid attributeClassId, AttributeImplementation implementation) - { - attributeImplementations[attributeClassId] = implementation; - } + public ClassImplementationRegistry ClassImplementations { get; } = new ClassImplementationRegistry(); public InstanceHandle Execute(OmsContext context, MethodBinding methodBinding, IInstanceReference? targetInstance = null) { @@ -1325,7 +1315,7 @@ public abstract class Oms Console.Error.WriteLine("oms: error: assigns from work data not set for parameter assignment '{0}'", parm.GlobalIdentifier); continue; } - + if (IsInstanceOf(assignsFromWorkData, GetInstance(KnownInstanceGuids.Classes.Class))) { assignsFromWorkData = context.GetWorkData(assignsFromWorkData); @@ -1380,7 +1370,7 @@ public abstract class Oms } else { - if (methodImplementations.ContainsKey(parentClassId)) + if (ClassImplementations.TryGet(parentClassId, out MethodImplementation? impl)) { if (targetInstance == null) { @@ -1435,15 +1425,14 @@ public abstract class Oms InstanceHandle pclassInstance = GetParentClass(hh); context.SetWorkData(pclassInstance, hh); } - retval = methodImplementations[parentClassId].Execute(this, context, methodOrMethodBinding); + retval = impl.Execute(this, context, methodOrMethodBinding); + } + else + { + throw new NotImplementedException(String.Format("method implementation not found for method class {0}", GetGlobalIdentifier(parentClass))); } } - if (retval == null) - { - // return InstanceHandle.Empty; - throw new NotImplementedException(String.Format("method implementation not found for method class {0}", GetGlobalIdentifier(parentClass))); - } - else + if (retval != null) { // context.StackTrace.Pop(); IDictionary dict = context.GetAllWorkData(); @@ -1455,6 +1444,11 @@ public abstract class Oms } return retval.Value; } + else + { + // return InstanceHandle.Empty; + throw new InvalidOperationException(String.Format("method did not return work data for method class {0}", GetGlobalIdentifier(parentClass))); + } } private InstanceHandle ExecuteMethodBinding(OmsContext context, InstanceHandle methodBinding, IInstanceReference? targetInstance = null) @@ -2787,10 +2781,6 @@ public abstract class Oms Guid classGuid = GetGlobalIdentifier(parentClass); // find AttributeImplementation whose ClassGuid matches - if (attributeImplementations.ContainsKey(classGuid)) - { - return attributeImplementations[classGuid]; - } - throw new NotImplementedException(String.Format("implementation for attribute class {0} not found", classGuid)); + return ClassImplementations.Get(classGuid); } }