StefH / ProxyInterfaceSourceGenerator

This project uses Source Generation to generate an interface and a Proxy class for classes. This makes it possible to wrap external classes which do not have an interface, in a Proxy class which makes it easier to Mock and use Dependency Injection.
MIT License
36 stars 5 forks source link

v0.0.3 feedback #2

Closed beakona closed 1 year ago

beakona commented 2 years ago

Here are some cases that I find failing and/or cases that is not an error but I pointed them out just to be aware of....

  1. it is not allowed to put simple type name but only full name [ProxyInterfaceGenerator.Proxy(typeof(PITest.Some2.Person))] [ProxyInterfaceGenerator.Proxy(typeof(Person))]

  2. there is a case where _mapper is used but not assigned private readonly IMapper? _mapper; public string? Surname { get => _mapper.Map<string?>(_Instance.Surname); set => _Instance.Surname = _mapper.Map<string?>(value); } public PersonProxy(PITest.Some2.Person instance) { _Instance = instance; }

  3. generated code is not valid when there is no namespace (foreign class is in root scope)

  4. no support for generics public sealed class Person<T>

  5. no support for inner class [ProxyInterfaceGenerator.Proxy(typeof(PITest.Some.Person.Inner))]

  6. output filename clash in case with multiple interfaces with same name but different namespace [ProxyInterfaceGenerator.Proxy(typeof(PITest.Some.Person))] [ProxyInterfaceGenerator.Proxy(typeof(PITest.Some2.Person))]

  7. no support for events... maybe simple forwarders public event EventHandler<EventArgs>? Done { add { _Instance.Done += value; } remove { _Instance.Done -= value; }}

  8. do all reftypes should be mapped? public string? Surname { get => _mapper.Map<string?>(_Instance.Surname); set => _Instance.Surname = _mapper.Map<string?>(value); } public System.Threading.Tasks.Task Method1Async() => _mapper.Map<System.Threading.Tasks.Task>(_Instance.Method1Async());

  9. verbatim names (yes, I know...) public string @object { get; set; }

  10. ref and out are not being forwarded correctly public void Print((int x, int y) position, out int a, in int b, ref int c, int d = 5)

  11. interface methods do not propagate default value for parameters public void Print(int val = 5)

  12. params keyword is not emitted public void Print((int x, int y) position, params int[] d) public void Print((int x, int y) position, int[] d)

  13. no support for indexers public int this[in int a, int b = 5] { ... }

  14. for projects where #nullable is disabled emitting nullable reftype without preprocessor '#nullable enable' would result in compile time error.

StefH commented 2 years ago

@beakona Thank you for the extended review. This really helps me a lot.

I've created new issues, to make tracking easier.

And I'll close this one.

StefH commented 2 years ago

@beakona

See version 0.0.4 which fixes some issues. See releasenotes for info.

beakona commented 2 years ago

Everything looks good...

See if any of these helps:

StefH commented 2 years ago

@beakona I've fixed some bugs in 0.0.5 and 0.0.6, See releasenotes for details.

StefH commented 2 years ago

@beakona Some more issues are solved. See latest version + releasenotes.

StefH commented 2 years ago

@beakona latest version does fix some more issues. See releasenotes for details.

beakona commented 2 years ago

@StefH Recently I've find out that you can facilitate debugging of the source generator.. https://www.reddit.com/r/csharp/comments/mqzc4r/source_generators_has_anyone_figured_out_the_new/

StefH commented 2 years ago

@beakona

For debugging, there are multiple options:

  1. Use a #if DEBUG - #endif construction in the Initialize from the Source Generator
  2. Write Unit-Tests

For option 1: see also my blog https://mstack.nl/blog/20210801-source-generators/

For option 2: Based on the cookbook from source-generators + some other information, I've created a simple NuGet package which can be used to easily test a Source Generator.

See https://github.com/StefH/FluentBuilder/tree/main/src-extensions

beakona commented 2 years ago

There is also the third way where you can directly inspect variables (in 'attached' Visual Studio debugger) during 'compile'. Here is summary from the link I sent 9h ago.

  1. add <IsRoslynComponent>true </IsRoslynComponent> to .csproj of your SourceGenerator
  2. open Debug section of SourceGenerator properties and set 'Rosly Component' for Launch and your starting project for 'Target Project'. (hint, try reload project)
  3. set SourceGenerator project as Visual Studio startup project
  4. set some breakpoints
  5. press F5

I shared it with you because I find it handy to inspect inner workings of Roslyn ISymbol. I didn't know of this until few days ago..

StefH commented 2 years ago

@beakona Support for indexers has been added to latest release.

StefH commented 1 year ago

I think most issues are solved now.

Closing..