From 8d8c0584730647e9be0ab9a662a875362a8c45c0 Mon Sep 17 00:00:00 2001 From: SzymonPobiega Date: Thu, 17 Aug 2017 10:59:30 +0200 Subject: [PATCH] Allow statement-bodied properties in sagas --- ...est.WithStatementBodyProperty.approved.txt | 6 +++ .../Saga/SagaDefinitionReaderTest.cs | 30 ++++++++++++++ src/ScriptBuilder/CecilExtensions.cs | 41 ++++++++++++++++++- 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 src/ScriptBuilder.Tests/Saga/SagaDefinitionReaderTest.WithStatementBodyProperty.approved.txt diff --git a/src/ScriptBuilder.Tests/Saga/SagaDefinitionReaderTest.WithStatementBodyProperty.approved.txt b/src/ScriptBuilder.Tests/Saga/SagaDefinitionReaderTest.WithStatementBodyProperty.approved.txt new file mode 100644 index 000000000..bad9f5579 --- /dev/null +++ b/src/ScriptBuilder.Tests/Saga/SagaDefinitionReaderTest.WithStatementBodyProperty.approved.txt @@ -0,0 +1,6 @@ +{ + "TableSuffix": "WithStatementBodyPropertySaga", + "CorrelationProperty": null, + "TransitionalCorrelationProperty": null, + "Name": "SagaDefinitionReaderTest/WithStatementBodyPropertySaga" +} \ No newline at end of file diff --git a/src/ScriptBuilder.Tests/Saga/SagaDefinitionReaderTest.cs b/src/ScriptBuilder.Tests/Saga/SagaDefinitionReaderTest.cs index 389f28ac3..efd97c313 100644 --- a/src/ScriptBuilder.Tests/Saga/SagaDefinitionReaderTest.cs +++ b/src/ScriptBuilder.Tests/Saga/SagaDefinitionReaderTest.cs @@ -209,4 +209,34 @@ protected override void ConfigureMapping(IMessagePropertyMapper mapper) { } } + + [Test] + public void WithStatementBodyProperty() + { + var sagaType = module.GetTypeDefinition(); + SagaDefinitionReader.TryGetSqlSagaDefinition(sagaType, out var definition); + ObjectApprover.VerifyWithJson(definition); + } + + public class WithStatementBodyPropertySaga : SqlSaga + { + public class SagaData : ContainSagaData + { + } + + protected override string CorrelationPropertyName + { + //Explicitly not use expression body + get { return null; } + } + + protected override void ConfigureMapping(IMessagePropertyMapper mapper) + { + } + } + + public void Dispose() + { + module?.Dispose(); + } } \ No newline at end of file diff --git a/src/ScriptBuilder/CecilExtensions.cs b/src/ScriptBuilder/CecilExtensions.cs index 73e759af5..288ec4504 100644 --- a/src/ScriptBuilder/CecilExtensions.cs +++ b/src/ScriptBuilder/CecilExtensions.cs @@ -2,6 +2,7 @@ using System.Linq; using Mono.Cecil; using Mono.Cecil.Cil; +using Mono.Collections.Generic; using NServiceBus.Persistence.Sql; static class CecilExtensions @@ -42,10 +43,22 @@ public static bool TryGetPropertyAssignment(this PropertyDefinition property, ou { value = null; var instructions = property.GetMethod.Body.Instructions; - if (instructions.Count != 2) + if (instructions.Count == 2) { - return false; + //Ldstr-Ret + return TryGetExpressionBodyPropertyAssignment(instructions, out value); + } + if (instructions.Count == 6) + { + //Nop-Ldstr-Stloc.0-Br.S-Ldloc.0-Ret + return TryGetStatementBodyPropertyAssignment(instructions, out value); } + return false; + } + + static bool TryGetExpressionBodyPropertyAssignment(Collection instructions, out string value) + { + value = null; if (instructions[1].OpCode != OpCodes.Ret) { return false; @@ -63,6 +76,30 @@ public static bool TryGetPropertyAssignment(this PropertyDefinition property, ou return false; } + static bool TryGetStatementBodyPropertyAssignment(Collection instructions, out string value) + { + value = null; + if (instructions[5].OpCode != OpCodes.Ret + || instructions[4].OpCode != OpCodes.Ldloc_0 + || instructions[3].OpCode != OpCodes.Br_S + || instructions[2].OpCode != OpCodes.Stloc_0 + || instructions[0].OpCode != OpCodes.Nop) + { + return false; + } + var first = instructions[1]; + if (first.OpCode == OpCodes.Ldstr) + { + value = (string)first.Operand; + return true; + } + if (first.OpCode == OpCodes.Ldnull) + { + return true; + } + return false; + } + public static CustomAttribute GetSingleAttribute(this TypeDefinition type, string attributeName) { return type.CustomAttributes.SingleOrDefault(x => x.AttributeType.FullName == attributeName);