QRCoder
QRCoder copied to clipboard
[WIP/QRCoder2] Fluent API experimentation PR
Summary
Experimentation with fluent API syntax
Samples
var code = QRCodeBuilder.CreateEmail("[email protected]")
.WithSubject("Testing")
.WithBody("Hello World!")
.WithErrorCorrection(QRCodeGenerator.ECCLevel.H)
.RenderWith<AsciiRenderer>()
.WithQuietZone(false)
.ToString();
var image = QRCodeBuilder.CreatePhoneNumber("1234567890")
.WithErrorCorrection(QRCodeGenerator.ECCLevel.H)
.RenderWith<SystemDrawingRenderer>(20)
.WithQuietZone(false)
.ToBitmap();
var base64 = QRCodeBuilder.CreateMMS("1234567890", "Hello")
.RenderWith<PngRenderer>()
.ToBase64String();
Intellisense samples
Preliminary Findings
- Could start with
new QRCodeBuilder.Email("[email protected]")
rather thanQRCodeBuilder.CreateEmail("[email protected]")
- which is pretty similar to the existingnew PayloadGenerator.Wifi()
syntax actually, with the difference being the fluent syntax for configuration. One benefit of usingnew
is that additional payloads can be added by simply adding a new class into the correct namespace. Whereas methods cannot be added toQRCodeBuilder
outside of QRCoder. - Using
RenderWith<T>
breaks the intellisense pattern because T does not give a list of the specific renderers available. Probably better to create an extension method for each renderer, likeRenderAsAscii()
andRenderAsPng(20)
instead -
RenderWith<T>
does not allow for render-specific constructor parameters. I've compensated with support for only two patterns: (1) no arguments (2) pixels per module argument. HavingRenderAs...()
dedicated methods would allow each renderer to require specific arguments. - The builder syntax could likely be added to v1.x as a new layer, as shown in this PR, with any implementation changes we wish to make within the builder methods. Then v2 just removes (or makes internal) all the old methods.
- The new builders, when layered on the old code, are quite easy to write. Once the old code is removed, additional optimizations can be added to enhance trimming support. This trimming capability may consolidate the QRCode and ArtQRCode classes.
- All of the supporting code can be nested as deep within namespaces as desired, since intellisense always provides the correct context-sensitive methods. Except for
RenderWith<T>
, as noted in item 2 above. Another reason to useRenderAsAscii()
or similar. - The extension methods on the renderers (
ToArray
,ToStream
,ToFile
, etc) are really cool -- each renderer need only implementToStream
and all the other methods are available via extension methods. Similar functionality for text renderers; even with only implementingToString
they can also provideToFile
,ToStream
,ToBase64
, and so on via extension methods.