ironcev / awesome-roslyn

Curated list of awesome Roslyn books, tutorials, open-source projects, analyzers, code fixes, refactorings, and source generators

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WrapperValueObject source generator

YairHalberstadt opened this issue · comments

Saw this - thought it looked cool and you might be interested https://github.com/martinothamar/WrapperValueObject

Thanks @YairHalberstadt! Very simple but definitely cool. It demonstrates an additional area in which source generators can be used, for generating types with a predefined structure. A kind of a C# 9.0 record feature for structs in this case ;-)

It reminds me also of @andrewlock's excellent article series Using strongly-typed entity IDs to avoid primitive obsession and his StronglyTypeId project.

WrapperValueObject is still in a very early I would say PoC stage but demonstrate well an additional area of source generators usage so I would like to add it to the Awesome Roslyn list. @YairHalberstadt would you mind contributing and creating a pull request?

Excellent! I tried out a simple PoC of this a while ago, that looked almost exactly like this 🙂 Couldn't be more timely, seeing as the build for my StrongTypedId project seems to have imploded in an SDK update at some point 😫

@andrewlock although you've mentioned in the last article in the series that you do not see a value in porting StronglyTypedId to source generators, I would love to see that happening. The existing implementation is great and also the whole series of blog posts is the best read on the topic I came across. Having a C# 9.0 source generator of that quality would be great.

On the other hand, I would equally love to see @martinothamar's WrapperValueObject moving beyond the PoC, getting maybe cleaner API, Nuget package etc. At the moment it is a combination of a strongly typed id and an immutable struct generator.

Anyhow, thank you both for your inspiring work! :-)

Hey! Cool, thanks for the mention

A kind of a C# 9.0 record feature for structs in this case ;-)

My original motivation was simplifying lots of boilerplate related to value object structs in a previous project, but I also ended up at this exact conclusion - it's basically record feature for structs 🙂 C# 9 only comes with the record feature for classes thus far AFAIK, is that still correct? Do you know if there has been any consideration for doing it also for structs in the future? The .NET guidance for defining structs is to always implement GetHashCode and Equals AFAIK since if equality/hashcode is used in any way without those implementations it will have massive performance implications (experienced this in production once)

WrapperValueObject is still in a very early I would say PoC stage

Indeed it is, haven't used this much yet. But since it got some interest I'll add some polish and get a proper nuget package out. Suggestions etc are welcome 👍

@martinothamar

For me my main usage would be creating strongly typed wrappers for primitives - eg. MetersLength which wraps int, and can be implicitly cast between the two.

I think you already generate all that, but some documentation on what's generated would be useful!

Do you know if there has been any consideration for doing it also for structs in the future?

That's planned for C# 10

That was my usecase as well, awesome, will put in some docs work and publish 👍

I'd be keen to retire my StronglyTypedId package in favour of your source generator version too - my intention was to rewrite StronglyTypedId using source gens once it went GA, but looks like you've saved me the trouble 😀 There may be space for both of them, serving slightly different goals, but we'll see - if I can get away using yours that sounds good to me 🙂

My suggestion (I hope I am not shooting too far :-)) is to bring WrapperValueObject to a production level and to have the strongly typed ids as one of the supported use cases:

  • Improve API:
    • Replace one generic attribute (WrapperValueObject) with two (or more) that cleary identify the usecase. E.g. StronglyTypedIdAttribute, ImmutableStructAttribute, ...
  • Support everything that StronglyTypedId supports (e.g. optional generation of JSON converters).
  • Bring the documentation to the same level as in the StronglyTypedId project.
  • Write tests.
  • Create Nuget package.

@ironcev that sounds good to me, I can try to get there and maybe @andrewlock can review eventually, then we can see how it works out. I'm open to any solution, and agree with the usecases here 🙂

Hi again, I have pushed some updates

  • Improved README
  • NuGet package
  • More tests (still more needed)
  • Support more of StronglyTypedId functionality (JsonConverter is the remaining piece I think)

Other than that not quite sure on how to improve the API/Attribute(s). Been thinking of maybe having 1 attribute per primitive type for example - IntWrapperType, FloatWrapperType etc. Some of the code that is being generated should probably also be configurable, for instance maybe you don't want implicit casts. But I think this is an OK start at least.

Looks good, thanks for your commitment @martinothamar :-) Regarding the API improvements and other ideas, I propose to move the discussion to the WrapperValueObject repository and use dedicated GitHub issues for that. I am interested in seeing the project getting developed further and can formulate the proposals more precisely in GitHub issues. That way it will be much easier to discuss and refine them one by one.