-
-
Notifications
You must be signed in to change notification settings - Fork 138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support DI registration methods #202
Comments
I can see you want to go with source code generation consistently for everything, makes sense. In this case how would you feel about following approach. This would be analogical to the mappers, and would address your concern about generating public code w/o user awareness. // mapperly abstractions - probably better name
public class AddMappersAttribute : Attribute
{
public AddMappersAttribute(ServiceLifetime lifetime, params Type[] mappers)...
}
// user code
public static partial class MyComponentExtensions
{
public static IServiceCollection AddMyComponent(this IServiceCollection services) => services
.AddTransient<IFoo, Foo>()
.AddTransientMappersNameDoesntMatter()
.AddSigneletonMappers();
[AddMappers(ServiceLifetime.Transient, typeof(CarMapper), typeof(CustomerMapper))]
private static partial IServiceCollection AddTransientMappersNameDoesntMatter(this IServiceCollection services);
[AddMappers(ServiceLifetime.Singleton, typeof(ShopMapper), typeof(InvoiceMapper))]
private static partial IServiceCollection AddSingletonMappers(this IServiceCollection services);
} this would generate code similar to this one public static partial class MyComponentExtensions
{
private static partial IServiceCollection AddTransientMappersNameDoesntMatter(this IServiceCollection services) => services
.AddTransient<CarMapper>()
.AddTransient<CustomerMapper>();
private static partial IServiceCollection AddSingletonMappers(this IServiceCollection services) => services
.AddSingleton<ShopMapper>()
.AddSingleton<InvoiceMapper>();
} |
It would be nice to have the possibility of registering mappers with the DI container extended with some form of abstractions to allow taking dependencies on some known contract instead of the individual mapper implementations. It should be possible to source generate interface implementations, the MVVM toolkit already does something like this. It could look something like this:
|
On a second thought, I think Mapperly should keep the principle of only generating implementations for user defined partial methods and Mapperly-Private methods. This keeps the features discoverable and less magical to the user. Closing this for now. |
Oh man! I just found this cool library. Thank's for building it <3 I'm comming from AutoMapper (just as everybody, I guess). class EndpointBase<TRequest,TCommand>(IMapper mapper)
{
public TCommand CreateCommand(TRequest req) =>
mapper.Map<TRequest, TCommand>(req)
} I think this could be achieved by this lib, too. public interface IMapper { }
public interface IMapper<TSource, TTarget> : IMapper
{
TTarget Map<TSource, TTarget>(TSource source);
} This interface could be added by the source gen to each mapper class. The For DI to work, there should be a static partial class ServiceExtensions
{
[MapperExtensionMethod(ServiceScope = Scoped)]
public static partial IServiceCollection AddMyMappers(this IServiceCollection services);
} The source gen would then create a method like this containing all the mappers: public static partial IServiceCollection AddMyMappers(this IServiceCollection services)
{
services.AddScoped<IMapper<Car, CarDto>, CarMapper>();
services.AddScoped<IMapper<Cat, CatDto>, OtherMapper>();
services.AddScoped<IMapper<Dog, DogDto>, OtherMapper>();
return services;
} This would enable users of the lib to register mappers with DI and consume them via the I know there are some edge cases, where other method signatures are supported for the mapping methods. @latonz What do you think? Should I prepare a PR? |
Thanks for your feedback and willingness to prepare a PR! 😊 New contributors are always welcome. I'm not really sure if I understand your comment correctly. If not, could you provide an example of what the generated code would look like for the feature you are requesting? As far as I understand your comment there are two requests:
My two cents:
Before you start working on an implementation, we should discuss this matter further until we have a concrete plan of what should be implemented and how. |
Via an option on the
MapperAttribute
, extension methods to the IServiceCollection should be generated to add a single mapper by its name or all mappers at once to the service collection. By default these should be added as singletons, but an overload with a service lifetime should be available.Example of how the generated code could look like:
tbd: currently, Mapperly only generates implementations for user defined partial methods and Mapperly-internal private methods. This would generate public accessible code, without the user defining it. Does that have any implications on usability?
The text was updated successfully, but these errors were encountered: