diff --git a/README.md b/README.md index 0ddb217f53..a87fa4dba5 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,13 @@ [![Sparkline](https://stars.medv.io/stevedunn/vogen.svg)](https://stars.medv.io/stevedunn/vogen) ## Give a Star! :star: If you like or are using this project please give it a star. Thanks! + +Pronounced "Voh Jen" + + # Vogen: cure your Primitive Obsession diff --git a/assets/voh-jen.wav b/assets/voh-jen.wav new file mode 100644 index 0000000000..b0de9c8552 Binary files /dev/null and b/assets/voh-jen.wav differ diff --git a/docs/site/Writerside/topics/reference/Configuration.md b/docs/site/Writerside/topics/reference/Configuration.md index bb0a9fe17c..99e35467cf 100644 --- a/docs/site/Writerside/topics/reference/Configuration.md +++ b/docs/site/Writerside/topics/reference/Configuration.md @@ -31,6 +31,7 @@ Most values are present in both `ValueObject` and `VogenDefaults`. The parameter * `parsableForPrimitives` - specifies what is generated for `Parse` and `TryParse` methods - defaults to `ParsableForPrimitives.HoistMethodsAndInterfaces` * `tryFromGeneration` - specifies what to write for `TryFrom` methods—defaults to `TryFromGeneration.GenerateBoolAndErrorOrMethods` * `isInitializedMethodGeneration` - specifies whether to generate an `IsInitialized()` method - defaults to `IsInitializedMethodGeneration.Generate` +* `primitiveEqualityGeneration` - specified whether to generate primitive comparison operators. The values that are specified only to global configuration are: @@ -39,6 +40,7 @@ The values that are specified only to global configuration are: * `openApiSchemaCustomizations` - determines what is generated to assist in OpenAPI scenarios, for instance, generate a schema filter for Swashbuckle, or generate an extension method with `MapType` calls - defaults to `OpenApiSchemaCustomizations.Omit` * `explicitlySpecifyTypeInValueObject` - specifies whether individual value objects should explicitly define the primitive type that they wrap - defaults to `false` +* `disableStackTraceRecordingInDebug` - disables stack trace recording; in Debug buids, a stack trace is recorded and is thrown in the exception when something is created in an uninitialized state, e.g. after deserialization Several code analysis warnings exist for invalid configuration, including: diff --git a/docs/site/Writerside/topics/reference/FAQ.md b/docs/site/Writerside/topics/reference/FAQ.md index 213a4d4e41..e69e9cccf3 100644 --- a/docs/site/Writerside/topics/reference/FAQ.md +++ b/docs/site/Writerside/topics/reference/FAQ.md @@ -526,4 +526,38 @@ There are two solutions: } ... +``` + +### Are value objects any bigger than the primitives that they wrap? +They are by default, but they can be configured so that they're not. + +They're bigger because Vogen generates code that stores a field named `_isInitialized`. This +is used to check that the instance is initialized, e.g. after deserializing. +If you don't want that, then you can specify in your project that you don't want validation, e.g. + +```xml + + Exe + net8.0 + ➕ VOGEN_NO_VALIDATION + +``` + +With this set, when we run in debug mode, we can see that there's no size difference: + +```c# +[ValueObject] +public readonly partial struct Age; + +Console.WriteLine(Marshal.SizeOf()); +Console.WriteLine(Marshal.SizeOf()); + +// outputs 4, 4 +``` + +In debug builds, Vogen, by default, includes a stack trace field. This is used in the exception when an uninitialized value object is accessed. +If it is important that your debug builds have the same size value objects as your release builds, then add the following in your global config: + +```c# +[assembly: VogenDefaults(disableStackTraceRecordingInDebug: true)] ``` \ No newline at end of file diff --git a/src/Vogen.SharedTypes/VogenDefaultsAttribute.cs b/src/Vogen.SharedTypes/VogenDefaultsAttribute.cs index 4f5f7ae16c..de8a9c30e9 100644 --- a/src/Vogen.SharedTypes/VogenDefaultsAttribute.cs +++ b/src/Vogen.SharedTypes/VogenDefaultsAttribute.cs @@ -29,8 +29,8 @@ public class VogenDefaultsAttribute : Attribute /// Controls how cast operators are generated for casting from the primitive to the Value Object. /// Options are implicit or explicit or none. Explicit is preferred over implicit if you really need them, but isn't recommended. /// See <see href="https://github.com/SteveDunn/Vogen/wiki/Casting"/> for more information. - /// If Debug, a stack trace is recorded if something is created in an uninitialized state. - /// This stack trace is heap based which might be unwanted if your Value Object is stack based. + /// disables stack trace recording; in Debug builds, a stack trace is recorded and is + /// thrown in the exception when something is created in an uninitialized state, e.g. after deserialization /// Specifies the functionality around parsing (IParsable etc.) /// Specifies the functionality around parsing (IParsable etc.) /// Controls what is generated for the TryFrom methods. diff --git a/tests/SnapshotTests/GeneralStuff/GeneralTests.cs b/tests/SnapshotTests/GeneralStuff/GeneralTests.cs index 96b4d5f097..1e85280aa1 100644 --- a/tests/SnapshotTests/GeneralStuff/GeneralTests.cs +++ b/tests/SnapshotTests/GeneralStuff/GeneralTests.cs @@ -35,6 +35,25 @@ public partial class MyVo; .RunOn(TargetFramework.Net8_0); } + [Fact] + public async Task Disable_stack_trace_in_debug() + { + var source = + """ + using System; + using Vogen; + + [assembly: VogenDefaults(disableStackTraceRecordingInDebug: true)] + + [ValueObject] + public partial class MyVo; + """; + + await new SnapshotRunner() + .WithSource(source) + .RunOn(TargetFramework.Net8_0); + } + [Theory] [InlineData("struct")] [InlineData("class")] diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Disable_stack_trace_in_debug.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Disable_stack_trace_in_debug.verified.txt new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Disable_stack_trace_in_debug.verified.txt @@ -0,0 +1 @@ + \ No newline at end of file