Starts in:
2 DAYS
16 HRS
36 MIN
23 SEC
Starts in:
2 D
16 H
36 M
23 S
Open Closed

Apply database migration - Event handler not working #3102


User avatar
0
lalitChougule created
  • ABP Framework version: v4.3.1
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): no / yes
  • Exception message and stack trace: N.A
  • Steps to reproduce the issue:" N.A

Hi,

When I click on the Apply database migration in image 1, I only get message as per image 2 and image 3 shows the network tab

Now, I have created an Event Handler like below, but none of the below methods executes. Debugger also hit on these methods.

public class XYZServiceDatabaseMigrationEventHandler : IDistributedEventHandler<TenantCreatedEto>,
        IDistributedEventHandler<TenantConnectionStringUpdatedEto>,
        IDistributedEventHandler<ApplyDatabaseMigrationsEto>
    {
        public async Task HandleEventAsync(TenantCreatedEto eventData)
        {
            //Some code
        }

        public async Task HandleEventAsync(TenantConnectionStringUpdatedEto eventData)
        {
            //Some code
        }

        public async Task HandleEventAsync(ApplyDatabaseMigrationsEto eventData)
        {
            //Some code
        }
    }

23 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Try ITransientDependency

    public class XYZServiceDatabaseMigrationEventHandler : ITransientDependency
    
    
  • User Avatar
    0
    lalitChougule created

    Hi still not working with ITransientDependency

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can debug the TenantAppService to check the events are published.

    override some method of TenantAppService, download the source code of saas module.

  • User Avatar
    0
    lalitChougule created

    Hi mailming

    This is TenantAppService source code https://github.com/abpframework/abp/blob/4.3.1/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs

    There are no events published here Also there is no method called ApplyDatabaseMigrations in this AppService.

    Please can you guide us with sample code or something as this activity is on priority for us.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    You need to check the source code of Saas module.

    https://docs.abp.io/en/commercial/latest/modules/saas

  • User Avatar
    0
    lalitChougule created

    Hi,

    I tired overriding TenantAppService , code as below :

    using Microsoft.Extensions.Localization;
    using Microsoft.Extensions.Options;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Volo.Abp.Application.Dtos;
    using Volo.Abp.Data;
    using Volo.Abp.DependencyInjection;
    using Volo.Abp.EventBus.Distributed;
    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), typeof(TenantAppService))]
        public class CustomTenantAppService : TenantAppService, 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)
                : base(tenantRepository,
                      editionRepository,
                      tenantManager,
                      dataSeeder,
                      distributedEventBus,
                      dbConnectionOptions)
            {
                EditionRepository = editionRepository;
                DataSeeder = dataSeeder;
                DistributedEventBus = distributedEventBus;
                DbConnectionOptions = dbConnectionOptions.Value;
                TenantRepository = tenantRepository;
                TenantManager = tenantManager;
            }
    
            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
                        }
                    );
                }
            }
        }
    }
    
    

    My swagger is showing error now as below :

    Log:

    2022-05-19 18:22:36.176 +05:30 [ERR] An unhandled exception has occurred while executing the request.
    Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException: Conflicting method/path combination "POST api/app/custom-tenant/{id}/apply-database-migrations" for actions - SCV.Litmus.LitmusTenants.CustomTenantAppService.ApplyDatabaseMigrationsAsync (SCV.Litmus.Application),SCV.Litmus.LitmusTenants.CustomTenantAppService.ApplyDatabaseMigrationsAsync (SCV.Litmus.Application). Actions require a unique method/path combination for Swagger/OpenAPI 3.0. Use ConflictingActionsResolver as a workaround
       at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GenerateOperations(IEnumerable`1 apiDescriptions, SchemaRepository schemaRepository)
       at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GeneratePaths(IEnumerable`1 apiDescriptions, SchemaRepository schemaRepository)
       at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwagger(String documentName, String host, String basePath)
       at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
       at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
       at Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
       at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
       at SCV.Litmus.LitmusHttpApiHostModule.<>c.<<OnApplicationInitialization>b__9_0>d.MoveNext() in D:\Litmus\Projects\multi-tenancy\SCV.Litmus\aspnet-core\gateways\SCV.Litmus.HttpApi.Host\LitmusHttpApiHostModule.cs:line 217
    --- End of stack trace from previous location ---
       at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
       at Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
       at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
    

    Also If you can give advice me on adding 3 new string properties in SaasTenantCreateDto which I want to Insert into SaasTenantConnectionStrings table.

    Please answer both of my queries. Thanks !!!

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    public async Task ApplyDatabaseMigrationsAsync(Guid id)

    Where is the override keyword?

    If you can give advice me on adding 3 new string properties in SaasTenantCreateDto which I want to Insert into SaasTenantConnectionStrings table.

    You can consider adding the source code of Saas to your project. Or use Object Extensions https://docs.abp.io/en/abp/latest/Object-Extensions

    SaasTenantCreateDto has implemented ExtensibleObject

  • User Avatar
    0
    lalitChougule created

    Where is the override keyword?

    This is the code from Saas Module

    [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
                        }
                    );    
                }
            }
    

    ApplyDatabaseMigrationsAsync method is not virtual so we cannot override it

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    then copy all code form TenantAppService to your CustomTenantAppService

     [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(ITenantAppService))]
    public class CustomTenantAppService : ITenantAppService
    
  • User Avatar
    0
    lalitChougule created

    Hi @maliming

    Now I am able to debug the code, now the issue is I am not able to get Database name here I am able to get connection string but not able to get database name. I have 4 connection string for each tenant

  • User Avatar
    0
    alper created
    Support Team Director

    write your connection strings pls

  • User Avatar
    0
    lalitChougule created

    write your connection strings pls

    Sorry I didn't get you !!!

  • User Avatar
    0
    alper created
    Support Team Director

    looks like your connection strings are not properly parsed

  • User Avatar
    0
    lalitChougule created

    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
                        }
                    );
                }
            }
        }
    }
    
    

    Error :

    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.&lt;&gt;c__DisplayClass5_0.&lt;CreateControllerFactory&gt;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.&lt;InvokeNextExceptionFilterAsync&gt;g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
    

    Please suggest.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    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.

    hi

    You should use ITenantAppService in the controller instead of CustomTenantAppService

    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(ITenantAppService))]
    public class CustomTenantAppService : ApplicationService, ITenantAppService
    

    Then use the ObjectMapper property.

  • User Avatar
    0
    lalitChougule created

    You should use ITenantAppService in the controller instead of CustomTenantAppService

    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.&lt;&gt;c__DisplayClass5_0.&lt;CreateControllerFactory&gt;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.&lt;InvokeNextExceptionFilterAsync&gt;g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    'SCV.Litmus.LitmusTenants.CustomTenantAppService' has not been registered.

    hi

    Try this.

    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(ITenantAppService), typeof(CustomTenantAppService ))]
    public class CustomTenantAppService : ApplicationService, ITenantAppService
    
  • User Avatar
    0
    lalitChougule created

    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.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    I tried by inheriting LitmusAppService

    Can you share the code?

  • User Avatar
    0
    lalitChougule created

    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.&lt;&gt;c__DisplayClass5_0.&lt;CreateControllerFactory&gt;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.&lt;InvokeNextExceptionFilterAsync&gt;g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Are you sure the error is the same? Please check the error logs.

    Do not inject other app services into the app service.

  • User Avatar
    0
    lalitChougule created

    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.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    ok, you can create a new projectand reproduce the problem then share it with me. liming.ma@volosoft.com

Made with ❤️ on ABP v9.1.0-preview. Updated on November 20, 2024, 13:06