Open agustinsilvano opened 3 months ago
This is because you are using the Auto API Controllers: https://docs.abp.io/en/abp/latest/API/Auto-API-Controllers
You can try:
[RemoteService(IsEnabled = false)]
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserAppService), typeof(UserAppService))]
public class UserAppService : IdentityUserAppService
and add a new controller to expose the endpoint
@realLiangshiwei got it.
If I add a custom method on the AppService, I must create the corresponding endpoint on the extended controller, right?
Just want to understand what is the recommended approach.
To wrap up, I was able to get it working properly by adding the [RemoteService(IsEnabled = false)]
to the AppService and by having the following code on the controller:
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IdentityUserController), IncludeSelf = true)]
public class UserController : IdentityUserController, IUserAppService
{
protected IUserAppService CustomUserAppService { get; }
public UserController(IIdentityUserAppService identityUserAppService, IUserAppService userAppService) : base(identityUserAppService)
{
CustomUserAppService = userAppService;
}
[HttpGet]
[Route("custom-endpoint")]
public virtual async Task<int> CustomEndpointAsync()
{
return await CustomUserAppService.CustomEndpointAsync();
}
}
@realLiangshiwei thanks!
@realLiangshiwei Sorry, circling back on this, that change updates correctly the HTTP layer but there is an issue while using the new app service. It throws:
2024-06-07 14:39:21.224 -03:00 [ERR] An exception was thrown while activating Acme.BookStore.Controllers.UserController.
Autofac.Core.DependencyResolutionException: An exception was thrown while activating Acme.BookStore.Controllers.UserController.
---> Autofac.Core.DependencyResolutionException: None of the constructors found on type 'Acme.BookStore.Controllers.UserController' can be invoked with the available services and parameters:
Cannot resolve parameter 'Acme.BookStore.IUserAppService userAppService' of constructor 'Void .ctor(Volo.Abp.Identity.IIdentityUserAppService, Acme.BookStore.IUserAppService)'.
This is my AppService class definition:
[RemoteService(IsEnabled = false)]
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserAppService), typeof(UserAppService))]
public class UserAppService : IdentityUserAppService, IUserAppService, ITransientDependency
I was able to get it working by manually registering the DI on the Application module.
public override void ConfigureServices(ServiceConfigurationContext context)
{
//...
context.Services.AddScoped<IUserAppService>(
sp => sp.GetRequiredService<UserAppService>()
);
}
Is that expected? What's the correct setup?
[RemoteService(IsEnabled = false)]
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserAppService), typeof(IUserAppService))]
public class UserAppService : IdentityUserAppService, IUserAppService, ITransientDependency
@realLiangshiwei that didn't work.
What is your code and what is the error log
Is there an existing issue for this?
Description
I'm customizing the IdentityUserAppService as described in the documentation.
While doing that, the underlying services are available and the ability to extend the app service by introducing new methods in the app service works fine.
The issue is that when the swagger documentation (HttpApi layer) is generated, either the
IdentityUserAppService
(existing AbpIdentity module) and either theUserAppService
(AppService that extends the existing one) endpoints are shown.My understanding is that by using
[Dependency(ReplaceServices = true)]
that should replace the default registered service with the custom one on the DI container. I'm not sure if that DI configuration should affect something on the endpoint discovery phase in order to ignore the endpoints defined in the base class (existing identity module).As an aside observation, the endpoint generation differs from the existing module to the custom one. The
FindBy
methods are generating a different output. So, I realized that you have a controller there that is the one that is generating the endpoints prefixed with/api/identity
The question is, is there a way to get rid of that controller? I tried overriding a controller but couldn't avoid the controller layer generation that is the one that is causing.
For adding new endpoints to the existing module, is the process customizing the AppService, excluding the AppService from the Api discovery phase, and exposing it through a customized controller?
I do not see the added value of controllers here they are being used as a facade. Is there any reason?
Reproduction Steps
Minimal sample project available here.
Expected behavior
The endpoint generation by extending (by inheritance) an existing AppService shouldn't generate duplicated endpoints on the Swagger Documentation.
Actual behavior
No response
Regression?
No response
Known Workarounds
No response
Version
8.1.3
User Interface
Common (Default)
Database Provider
EF Core (Default)
Tiered or separate authentication server
None (Default)
Operation System
Windows (Default)
Other information
No response