JasonBock / InlineMapping

Using the Compiler API for object mapping
MIT License
63 stars 11 forks source link

Update for Source Generators #1

Closed JasonBock closed 3 years ago

JasonBock commented 3 years ago

It's time :)

This basically means I "trash" what's there (it's really old, targets .NET Framework 4.6.1, etc.), and start over with a source generators project. The only thing I really want to save is UsingInlineMapperCodeFix - well, the code within it.

The main idea now is to create a MapToAttribute that is either applicable to a class or an assembly. If it's a class, it will take a Type that defines the destination it can be mapped to. If it's on an assembly, it can take a source and destination type. For the first release, I'll just support the class-targeted version.

The source generator will look for these attributes on classes, and generate extension methods with inlined mapping code that I've already created in UsingInlineMapperCodeFix. For example, if I have this:

[MapTo(typeof(Destination))]
[MapTo(typeof(AnotherDestination))]
public sealed class Source { }

The source generator will create this:

using AnyNamespacesThatDestinationTypesAreIn;

namespace TheNamespaceSourceIsIn
{
  public static class SourceMapToExtensions
  {
    public static Destination MapToDestination(this Source self) { ... }
    public static AnotherDestination MapToAnotherDestination(this Source self) { ... }
  }
}

Then a developer can write this:

var source = new Source();
var destination = source.MapToDestination();
var anotherDestination = source.MapToAnotherDestination();

Of course, there are collisions to be worried about here. For example, if AnotherDestination exists twice in two different namespaces, and a developer wants to support mappings for both, I can't define MapToAnotherDestination() two times. One possibility is to see if there would be any collisions, and then use the full type name (namespace + type name) in the extension method name. That would look kind of ugly, but it would work.

I'll also want to update it with the core setup I typically do with projects these days (see Rocks for the baseline).