Hi,
Could you please reply to this question ?
Hi,
I have added new Micro-Service into my Microservice architecture application solution.
For CurrentUser
I can only get phone number field
For CurrentTenant
I can only get the Id
[Authorize]
public Task<SampleDto> GetAuthorizedAsync()
{
var user = CurrentUser.UserName;
var tenant = CurrentTenant.Id;
return Task.FromResult(
new SampleDto
{
Value = 42
}
);
}
FYI
abp new XXX.XXXX.XXXXX -t module-pro -csf --no-ui -dbms PostgreSQL -v 4.4.4
Volo.Abp.IdentityServer.Application
in the .csproj file of Application
project, but for my newly created project this package was not installed and also when I tried to install this package I am not able to find it on nuget package manager ( Image for your reference below ) and when I tried editing the .csproj and try to add it there, this package is not getting resolved. i.e. Volo.Abp.IdentityServer.Application
Thanks!!!
Hi,
I need to override AbpTenantAppService.FindTenantByNameAsync()
method.
How do I do it ?
I tried it as per your documentation https://docs.abp.io/en/abp/latest/Customizing-Application-Modules-Overriding-Services#overriding-a-service-class , but not able to resolve this below issue
These are links to the code I need to override. https://github.com/abpframework/abp/blob/4.4.4/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantAppService.cs https://github.com/abpframework/abp/blob/4.4.4/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantController.cs
Thanks you !!!
LitmusAppService
is not like any other app service
It is the custom base AppService
which Inherit from ApplicationService
And yes I am sure I am getting the same error.
Can you share the code?
LitmusAppService :
public abstract class LitmusAppService : ApplicationService
{
protected LitmusAppService()
{
LocalizationResource = typeof(LitmusResource);
}
}
CustomTenantAppService :
namespace SCV.Litmus.LitmusTenants
{
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(ITenantAppService), typeof(CustomTenantAppService))]
public class CustomTenantAppService : LitmusAppService, ITenantAppService
{
protected IEditionRepository EditionRepository { get; }
protected IDataSeeder DataSeeder { get; }
protected IDistributedEventBus DistributedEventBus { get; }
protected ITenantRepository TenantRepository { get; }
protected ITenantManager TenantManager { get; }
private readonly ISharedAppServices _sharedAppServices;
protected AbpDbConnectionOptions DbConnectionOptions { get; }
public CustomTenantAppService(
ITenantRepository tenantRepository,
IEditionRepository editionRepository,
ITenantManager tenantManager,
IDataSeeder dataSeeder,
IDistributedEventBus distributedEventBus,
IOptions<AbpDbConnectionOptions> dbConnectionOptions,
SCV.Litmus.SharedAppService.ISharedAppServices sharedAppServices)
{
EditionRepository = editionRepository;
DataSeeder = dataSeeder;
DistributedEventBus = distributedEventBus;
DbConnectionOptions = dbConnectionOptions.Value;
TenantRepository = tenantRepository;
TenantManager = tenantManager;
_sharedAppServices = sharedAppServices;
}
}
}
Error :
[11:54:00 ERR] [null] The requested service 'SCV.Litmus.LitmusTenants.CustomTenantAppService' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
Autofac.Core.Registration.ComponentNotRegisteredException: The requested service 'SCV.Litmus.LitmusTenants.CustomTenantAppService' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
at Microsoft.AspNetCore.Mvc.Controllers.ServiceBasedControllerActivator.Create(ControllerContext actionContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
Thanks @maliming It is working as expected you can close this ticket now.
I just have one query if you can answer that before you close this ticket.
This is my LitmusAppService
public abstract class LitmusAppService : ApplicationService
{
protected LitmusAppService()
{
LocalizationResource = typeof(LitmusResource);
}
}
I tried by inheriting LitmusAppService
still it gave me the same error
But LitmusAppService
inherits from ApplicationService
, this is one and the same right ?
I mean I am still not getting it why it is not working when I inherit it from LitmusAppServie
and why it is working when I inherit it from ApplicationService
.
You should use
ITenantAppService
in the controller instead ofCustomTenantAppService
So you mean I should override Controller also ? Can you provide some sample code ? See I just have to play around with ApplyDatabaseMigrationAsync only, I dont need to override the whole service. Give me some sample code how I can override or make new service and implement this method in it. And it should be called from Saas Tenants options on UI as below
I tried this as well, getting same issue as below
[11:54:00 ERR] [null] The requested service 'SCV.Litmus.LitmusTenants.CustomTenantAppService' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
Autofac.Core.Registration.ComponentNotRegisteredException: The requested service 'SCV.Litmus.LitmusTenants.CustomTenantAppService' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
at Microsoft.AspNetCore.Mvc.Controllers.ServiceBasedControllerActivator.Create(ControllerContext actionContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
Hey Hi,
I was trying to refactor some code and lost my previous changes for my CustomTenantAppService. I tried rewriting it as below
CustomAppService:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Uow;
using Volo.Saas.Editions;
using Volo.Saas.Host;
using Volo.Saas.Host.Dtos;
using Volo.Saas.Tenants;
namespace SCV.Litmus.LitmusTenants
{
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(ITenantAppService))]
public class CustomTenantAppService : ITenantAppService
{
protected IEditionRepository EditionRepository { get; }
protected IDataSeeder DataSeeder { get; }
protected IDistributedEventBus DistributedEventBus { get; }
protected ITenantRepository TenantRepository { get; }
protected ITenantManager TenantManager { get; }
protected AbpDbConnectionOptions DbConnectionOptions { get; }
public CustomTenantAppService(
ITenantRepository tenantRepository,
IEditionRepository editionRepository,
ITenantManager tenantManager,
IDataSeeder dataSeeder,
IDistributedEventBus distributedEventBus,
IOptions<AbpDbConnectionOptions> dbConnectionOptions)
{
EditionRepository = editionRepository;
DataSeeder = dataSeeder;
DistributedEventBus = distributedEventBus;
DbConnectionOptions = dbConnectionOptions.Value;
TenantRepository = tenantRepository;
TenantManager = tenantManager;
}
public virtual async Task<SaasTenantDto> GetAsync(Guid id)
{
var tenant = ObjectMapper.Map<Tenant, SaasTenantDto>(
await TenantRepository.GetAsync(id)
);
if (tenant.EditionId.HasValue)
{
var edition = await EditionRepository.GetAsync(tenant.EditionId.Value);
tenant.EditionName = edition.DisplayName;
}
return tenant;
}
public virtual async Task<PagedResultDto<SaasTenantDto>> GetListAsync(GetTenantsInput input)
{
var count = await TenantRepository.GetCountAsync(input.Filter);
var list = await TenantRepository.GetListAsync(
input.Sorting,
input.MaxResultCount,
input.SkipCount,
input.Filter,
includeDetails: true
);
var tenantDtos = ObjectMapper.Map<List<Tenant>, List<SaasTenantDto>>(list);
if (input.GetEditionNames)
{
var editions = await EditionRepository.GetListAsync();
foreach (var tenant in tenantDtos)
{
var edition = editions.FirstOrDefault(e => e.Id == tenant.EditionId);
tenant.EditionName = edition?.DisplayName;
}
}
return new PagedResultDto<SaasTenantDto>(
count,
tenantDtos
);
}
[Authorize(SaasHostPermissions.Tenants.Create)]
public virtual async Task<SaasTenantDto> CreateAsync(SaasTenantCreateDto input)
{
Tenant tenant = null;
async Task CreateTenantAsync()
{
tenant = await TenantManager.CreateAsync(input.Name, input.EditionId);
if (!input.DefaultConnectionString.IsNullOrWhiteSpace())
{
tenant.SetDefaultConnectionString(input.DefaultConnectionString);
}
input.MapExtraPropertiesTo(tenant);
/* Auto saving to ensure TenantCreatedEto handler can get the tenant! */
await TenantRepository.InsertAsync(tenant, autoSave: true);
}
if (input.DefaultConnectionString.IsNullOrWhiteSpace())
{
/* Creating the tenant in the current UOW */
await CreateTenantAsync();
}
else
{
/* Creating the tenant in a separate UOW to ensure it is created
* before creating the database.
* TODO: We should remove inner UOW once https://github.com/abpframework/abp/issues/6126 is done
*/
using (var uow = UnitOfWorkManager.Begin(requiresNew: true))
{
await CreateTenantAsync();
await uow.CompleteAsync();
}
}
await DistributedEventBus.PublishAsync(
new TenantCreatedEto
{
Id = tenant.Id,
Name = tenant.Name,
Properties =
{
{"AdminEmail", input.AdminEmailAddress},
{"AdminPassword", input.AdminPassword}
}
}
);
return ObjectMapper.Map<Tenant, SaasTenantDto>(tenant);
}
[Authorize(SaasHostPermissions.Tenants.Update)]
public virtual async Task<SaasTenantDto> UpdateAsync(Guid id, SaasTenantUpdateDto input)
{
var tenant = await TenantRepository.GetAsync(id);
tenant.EditionId = input.EditionId;
await TenantManager.ChangeNameAsync(tenant, input.Name);
input.MapExtraPropertiesTo(tenant);
await TenantRepository.UpdateAsync(tenant);
return ObjectMapper.Map<Tenant, SaasTenantDto>(tenant);
}
[Authorize(SaasHostPermissions.Tenants.Delete)]
public virtual async Task DeleteAsync(Guid id)
{
var tenant = await TenantRepository.FindAsync(id);
if (tenant == null)
{
return;
}
await TenantRepository.DeleteAsync(tenant);
}
[Authorize(SaasHostPermissions.Tenants.ManageConnectionStrings)]
public virtual async Task<string> GetDefaultConnectionStringAsync(Guid id)
{
var tenant = await TenantRepository.GetAsync(id);
return tenant.FindDefaultConnectionString();
}
[Authorize(SaasHostPermissions.Tenants.ManageConnectionStrings)]
public virtual async Task UpdateDefaultConnectionStringAsync(Guid id, string defaultConnectionString)
{
Tenant tenant;
string oldValue;
using (var uow = UnitOfWorkManager.Begin(requiresNew: true))
{
tenant = await TenantRepository.GetAsync(id);
oldValue = tenant.FindDefaultConnectionString();
if (oldValue == defaultConnectionString)
{
return;
}
tenant.SetDefaultConnectionString(defaultConnectionString);
await TenantRepository.UpdateAsync(tenant);
await uow.CompleteAsync();
}
await DistributedEventBus.PublishAsync(
new TenantConnectionStringUpdatedEto
{
Id = tenant.Id,
Name = tenant.Name,
ConnectionStringName = Volo.Abp.Data.ConnectionStrings.DefaultConnectionStringName,
OldValue = oldValue,
NewValue = defaultConnectionString
}
);
}
[Authorize(SaasHostPermissions.Tenants.ManageConnectionStrings)]
public virtual async Task DeleteDefaultConnectionStringAsync(Guid id)
{
Tenant tenant;
string oldValue;
using (var uow = UnitOfWorkManager.Begin(requiresNew: true))
{
tenant = await TenantRepository.GetAsync(id);
oldValue = tenant.FindDefaultConnectionString();
if (oldValue == null)
{
return;
}
tenant.RemoveDefaultConnectionString();
await TenantRepository.UpdateAsync(tenant);
await uow.CompleteAsync();
}
await DistributedEventBus.PublishAsync(
new TenantConnectionStringUpdatedEto
{
Id = tenant.Id,
Name = tenant.Name,
ConnectionStringName = Volo.Abp.Data.ConnectionStrings.DefaultConnectionStringName,
OldValue = oldValue,
NewValue = null
}
);
}
[Authorize(SaasHostPermissions.Tenants.ManageConnectionStrings)]
public async Task ApplyDatabaseMigrationsAsync(Guid id)
{
await DistributedEventBus.PublishAsync(
new ApplyDatabaseMigrationsEto
{
TenantId = id,
DatabaseName = ConnectionStrings.DefaultConnectionStringName
}
);
foreach (var databaseInfo in DbConnectionOptions.Databases.Values)
{
if (!databaseInfo.IsUsedByTenants)
{
continue;
}
await DistributedEventBus.PublishAsync(
new ApplyDatabaseMigrationsEto
{
TenantId = id,
DatabaseName = databaseInfo.DatabaseName
}
);
}
}
}
}
And If write same code by just inheriting from SaasHostAppServiceBase
then all error goes away, but then I get runtime error as below :
[11:54:00 ERR] [null] The requested service 'SCV.Litmus.LitmusTenants.CustomTenantAppService' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
Autofac.Core.Registration.ComponentNotRegisteredException: The requested service 'SCV.Litmus.LitmusTenants.CustomTenantAppService' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
at Microsoft.AspNetCore.Mvc.Controllers.ServiceBasedControllerActivator.Create(ControllerContext actionContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
Please suggest.
write your connection strings pls
Sorry I didn't get you !!!