1

I implemented DDD using ABP framework, but I don't know which part is wrong. It's a simple project that follows the ABP tutorial.

use : .net6 telerik blazor mssql

Error: Autofac.Core.DependencyResolutionException: An exception was thrown while activating A.Blazor.Pages.Shared.CustomerGrid -\> A.Customers.CustomerAppService.
\---\> Autofac.Core.DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'A.Customers.CustomerAppService' can be invoked with the available services and parameters:
Cannot resolve parameter 'A.Customers.ICustomerRepository customerRepository' of constructor 'Void .ctor(A.Customers.ICustomerRepository)'.
at Autofac.Core.Activators.Reflection.ReflectionActivator.\<\>c__DisplayClass12_0.\<UseSingleConstructorActivation\>b__0(ResolveRequestContext ctxt, Action`1 next)    at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Builder.RegistrationBuilder`3.<>c__DisplayClass41_0.<PropertiesAutowired>b__0(ResolveRequestContext ctxt, Action`1 next)
at Autofac.Extras.DynamicProxy.RegistrationExtensions.\<\>c__DisplayClass8_0`3.<EnableInterfaceInterceptors>b__1(ResolveRequestContext ctxt, Action`1 next)
at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)    --- End of inner exception stack trace ---    at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action`1 next)    at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action`1 next)
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)
at Autofac.Core.Resolving.ResolveOperation.ExecuteOperation(ResolveRequest request)
at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)    at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters)
at Blazorise.ComponentActivator.CreateInstance(Type componentType)
at Microsoft.AspNetCore.Components.ComponentFactory.InstantiateComponent(IServiceProvider serviceProvider, Type componentType)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateChildComponentOnFrame(RenderTreeFrame& frame, Int32 parentComponentId)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewComponentFrame(DiffContext& diffContext, Int32 frameIndex)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(DiffContext& diffContext, Int32 frameIndex)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext& diffContext, Int32 newFrameIndex)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext& diffContext, Int32 newFrameIndex)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext& diffContext, Int32 newFrameIndex)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer renderer, RenderBatchBuilder batchBuilder, Int32 componentId, ArrayRange`1 oldTree, ArrayRange`1 newTree)
at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()

[Blazor]

  1. Paged.Shared > CustomerComboBox.raozr
@using A.Customers
<Telerik.Blazor.Components.TelerikComboBox 
                                           TItem="@CustomerDto"
                                           TValue="int"
                                           OnRead="@GetCustomer"
                                           Placeholder="Select Customer"
                                           ClearButton="true"
                                           TextField="@nameof(CustomerDto.name)"
                                           ValueField = "@nameof(CustomerDto.customer_id)"
                                           Value="@selectCustomer"


></Telerik.Blazor.Components.TelerikComboBox>
  1. Paged.Shared > CustomerComboBox.razor.cs
using A.Customers;
using System.Threading.Tasks;
using Telerik.Blazor.Components;

namespace A.Blazor.Pages.Shared
{
    public partial class CustomerCombo
    {
        private readonly ICustomerAppService _customerAppService;
        public int selectCustomer { get; set; }=0;

        public CustomerCombo(ICustomerAppService customerAppService)
        {
            _customerAppService = customerAppService;
        }

        public async Task GetCustomer(ComboBoxReadEventArgs args)
        {
            args.Data = await _customerAppService.GetCustomerAppService();
        }
    }
}

[Application.Contracts]

  1. Customers > CustomerDto.cs
namespace A.Customers
{
    public class CustomerDto
    {
        public int customer_id { get; set; }
        public string name { get; set; }
    }
}
  1. Customers > ICustomerAppService.cs
namespace A.Customers
{
    public interface ICustomerAppService : IApplicationService
    {
        Task<List<CustomerDto>> GetCustomerAppService();
    }
}

[Application]

  1. Customers > CustomerAppService.cs
using System.Collections.Generic;
using System.Threading.Tasks;

namespace A.Customers
{
    public class CustomerAppService : AAppService, ICustomerAppService
    {
        private readonly ICustomerRepository _customerRepository;

        public CustomerAppService(ICustomerRepository customerRepository)
        {
            _customerRepository = customerRepository;
        }   

        public async Task<List<CustomerDto>> GetCustomerAppService()
        {
            var customers = await _customerRepository.GetListCustomerAsync();
            return ObjectMapper.Map<List<Customer>, List<CustomerDto>>(customers);
        }

    }
}
  1. AAppService.cs
using ATAG.Localization;
using Volo.Abp.Application.Services;

namespace A;


public abstract class AAppService : ApplicationService
{
    protected AAppService()
    {
        LocalizationResource = typeof(AResource);
    }
}
  1. AApplicationAutiMapperProfile.cs
using AutoMapper;
using ATAG.Customers;

namespace A;

public class AApplicationAutoMapperProfile : Profile
{
    public AApplicationAutoMapperProfile()
    {
        CreateMap<Customer, CustomerDto>();
        CreateMap<CustomerDto, Customer>();
    }
}

[Domain]

  1. Customers > Customer.cs
namespace A.Customers
{
    public class Customer
    {
        public int customer_id { get; set; }
        public string name { get; set; }

    }
}
  1. Customers > ICustomerRepository.cs
using System.Collections.Generic;
using System.Threading.Tasks;

namespace A.Customers
{
    public interface ICustomerRepository
    {
        Task<List<Customer>> GetListCustomerAsync();
    }
}

[EFCore]

  1. Customers > CustomerRepository.cs
using Dapper;
using A.EntityFrameworkCore;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.Dapper;
using Volo.Abp.EntityFrameworkCore;

namespace A.Customers
{
    public class CustomerRepository : DapperRepository<ADbContext>, ICustomerRepository
    {
        public CustomerRepository(IDbContextProvider<ADbContext> dbContextProvider) : base(dbContextProvider)
        {
        }

        public async Task<List<Customer>> GetListCustomerAsync()
        {
            var dbConnection = await GetDbConnectionAsync();

            StringBuilder builder = new StringBuilder();

            builder.AppendFormat(@"
                SELECT cust_id, name
                FROM T_CUSTOMER );

            var customers = await dbConnection.QueryAsync<Customer>(
                builder.ToString(),
                null,
                transaction: await GetDbTransactionAsync(),
                commandType: CommandType.Text
            );
            List<Customer> emptyList = new List<Customer>();

                return (List<Customer>)customers;
        }

    }
}
  1. AEntityFrameworkCoreModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<ADbContext>(options =>
        {
            /* Remove "includeAllEntities: true" to create
             * default repositories only for aggregate roots */
            options.AddDefaultRepositories(includeAllEntities: true);
        });
}
Jackdaw
  • 7,626
  • 5
  • 15
  • 33
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Dec 09 '22 at 06:41
  • You need to check from which base class the `CustomerRepository` inherit or which interfaces it implements, and from which interfaces the `ICustomRepository` inherits. You can use this document for this. => https://docs.abp.io/en/abp/latest/Repositories#custom-repository-interface At first glance, it seemed to me that there were shortcomings. – berkansasmaz Dec 13 '22 at 06:55
  • I had the similar issue, but mine was about the Android SDK version. I've tried to provide the **solution** that worked out for me: https://stackoverflow.com/questions/77007907/depoloying-abp-framework-maui-application-to-android-11-device-throws-error – Ruslan Aug 30 '23 at 12:15

1 Answers1

0

The "ICustomerRepository" interface should inherit from "IDapperRepository" similar to how your CustomerRepository class does and the names of the fields you use in your database should have the same name:

In your database you have these fields cust_id, name

In your class you have these, customer_id, name

They should have the same name so that dapper can map them or you can create an alias in your query.

Washyn Acero
  • 174
  • 1
  • 8