diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c12af30..fd78521 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,10 +6,6 @@ on: pull_request: branches: [ master ] -permissions: - contents: read - packages: write - env: DOTNET_VERSION: "10.0.x" NODE_VERSION: "20" @@ -18,6 +14,9 @@ jobs: test: name: Test runs-on: ubuntu-latest + permissions: + contents: read + packages: read steps: - name: Checkout repository @@ -53,6 +52,9 @@ jobs: publish-github-packages: name: Publish to GitHub Packages runs-on: ubuntu-latest + permissions: + contents: read + packages: write needs: test steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ef799d2..ff97f34 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,11 +4,6 @@ on: release: types: [published] -permissions: - contents: read - packages: write - id-token: write - env: DOTNET_VERSION: "10.0.x" NODE_VERSION: "20" @@ -17,6 +12,9 @@ jobs: test: name: Test runs-on: ubuntu-latest + permissions: + contents: read + packages: read steps: - name: Checkout repository @@ -52,6 +50,10 @@ jobs: publish-github-packages: name: Publish Package to GitHub Packages and NuGet.org runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write needs: test steps: diff --git a/LogicBuilder.ComponentModel.Design.Serialization.Tests/DesignerSerializationManagerTests.cs b/LogicBuilder.ComponentModel.Design.Serialization.Tests/DesignerSerializationManagerTests.cs index b5d5d57..ceea72f 100644 --- a/LogicBuilder.ComponentModel.Design.Serialization.Tests/DesignerSerializationManagerTests.cs +++ b/LogicBuilder.ComponentModel.Design.Serialization.Tests/DesignerSerializationManagerTests.cs @@ -641,6 +641,36 @@ public void CreateInstance_ConvertsParametersForConstructor() } } + [Fact] + public void CreateInstance_ConvertsParametersForConstructor_WithConstructorParameterNotConvertable() + { + // Arrange + var manager = (IDesignerSerializationManager)new DesignerSerializationManager(); + + // Act + using (((DesignerSerializationManager)manager).CreateSession()) + { + // Assert + Assert.Throws(() => + manager.CreateInstance(typeof(TestClassWithConstructorWithNotConvertibleParameter), new object[] { 42, 43, new TestClass { Name = "Test" } }, "test", false)); + } + } + + [Fact] + public void CreateInstance_ConvertsParametersForConstructor_WithConstructorParameterThrowingInvalidCastException() + { + // Arrange + var manager = (IDesignerSerializationManager)new DesignerSerializationManager(); + + // Act + using (((DesignerSerializationManager)manager).CreateSession()) + { + // Assert + Assert.Throws(() => + manager.CreateInstance(typeof(TestClassWithConstructorWithParameteInvalidCastException), new object[] { 42, 43, "44" }, "test", false)); + } + } + [Fact] public void GetInstance_ReturnsInstanceByName() { @@ -1053,6 +1083,23 @@ public void GetSerializer_CachesSerializerDuringSession() } } + [Fact] + public void GetSerializer_CachesSerializerDuringSession_WithUnAssignableSubclasss() + { + // Arrange + var manager = new DesignerSerializationManager(); + + // Act + using (manager.CreateSession()) + { + var serializer1 = manager.GetSerializer(typeof(TestClassWithSerializer), typeof(TestSerializer)); + var serializer2 = manager.GetSerializer(typeof(TestClassWithSerializer), typeof(TestSerializerSubclass)); + + // Assert + Assert.NotSame(serializer1, serializer2); + } + } + [Fact] public void GetSerializer_UsesCustomSerializationProvider() { @@ -1175,11 +1222,29 @@ private class TestClass2 public string Name { get; set; } = string.Empty; } + private class TestClass3 : TestClass + { + } + private class TestClassWithConstructor(string value) { public string Value { get; } = value; } + private class TestClassWithConstructorWithNotConvertibleParameter(string value1, int value2, TestClass3 value3) + { + public string Value1 { get; } = value1; + public int Value2 { get; } = value2; + public TestClass Value3 { get; } = value3; + } + + private class TestClassWithConstructorWithParameteInvalidCastException(string value1, int value2, DateTime value3) + { + public string Value1 { get; } = value1; + public int Value2 { get; } = value2; + public DateTime Value4 { get; } = value3; + } + private class TestComponent : Component { } @@ -1194,6 +1259,11 @@ private class TestClassWithSerializer { } + [DesignerSerializer(typeof(TestClass), typeof(TestClass))] + private class TestClassWithIncorrectSerializer + { + } + [DefaultSerializationProvider(typeof(TestDefaultSerializationProvider))] private class TestSerializerWithDefaultProvider { @@ -1207,6 +1277,10 @@ private class TestSerializer { } + private class TestSerializerSubclass : TestSerializer + { + } + private class TestDefaultSerializationProvider : IDesignerSerializationProvider { public object? GetSerializer(IDesignerSerializationManager manager, object? currentSerializer, Type? objectType, Type serializerType) diff --git a/LogicBuilder.ComponentModel.Design.Serialization/DesignerSerializationManager.cs b/LogicBuilder.ComponentModel.Design.Serialization/DesignerSerializationManager.cs index 9d6b7c0..f995dd8 100644 --- a/LogicBuilder.ComponentModel.Design.Serialization/DesignerSerializationManager.cs +++ b/LogicBuilder.ComponentModel.Design.Serialization/DesignerSerializationManager.cs @@ -14,7 +14,7 @@ namespace LogicBuilder.ComponentModel.Design.Serialization { /// Provides an implementation of the interface. - public class DesignerSerializationManager : IDesignerSerializationManager, IServiceProvider + public class DesignerSerializationManager : IDesignerSerializationManager { [ExcludeFromCodeCoverage] private sealed class SerializationSession : IDisposable @@ -355,7 +355,7 @@ PropertyDescriptorCollection IDesignerSerializationManager.Properties array = new PropertyDescriptor[propertyDescriptorCollection.Count]; for (int i = 0; i < array.Length; i++) { - array[i] = this.WrapProperty(propertyDescriptorCollection[i], obj); + array[i] = WrapProperty(propertyDescriptorCollection[i], obj); } } this.properties = new PropertyDescriptorCollection(array); @@ -489,26 +489,31 @@ protected virtual object CreateInstance(Type type, ICollection arguments, string bool flag2 = true; for (int k = 0; k < array2.Length; k++) { - if (!(array2[k] == null) && !parameters[k].ParameterType.IsAssignableFrom(array2[k])) + if (array2[k] != null && !parameters[k].ParameterType.IsAssignableFrom(array2[k])) { if (array[k] is IConvertible convertible) { try { array3[k] = convertible.ToType(parameters[k].ParameterType, null); - goto IL_219; } - catch (InvalidCastException) + catch (Exception e) when (e is FormatException || e is InvalidCastException) { // Type conversion failed - this constructor parameter doesn't match. - // Fall through to set flag2 = false and break. + flag2 = false; + break; } } - flag2 = false; - break; + else + { + flag2 = false; + break; + } + } + else + { + array3[k] = array[k]; } - array3[k] = array[k]; - IL_219:; } if (flag2) { @@ -604,7 +609,7 @@ public object GetSerializer(Type objectType, Type serializerType) if (this.serializers != null) { obj = this.serializers[objectType]; - if (obj != null && !serializerType.IsAssignableFrom(obj.GetType())) + if (obj != null && !serializerType.IsInstanceOfType(obj)) { obj = null; } @@ -768,7 +773,7 @@ protected virtual void OnSessionDisposed(EventArgs e) } } - private PropertyDescriptor WrapProperty(PropertyDescriptor property, object owner) + private static PropertyDescriptor WrapProperty(PropertyDescriptor property, object owner) { if (property == null) {