Base solution for your next web application
Open Closed

ABP Plugin Module fails to load with error AppAervice is waiting for the following dependencies: - Service 'Abp.Domain.Repositories.IRepository`2 #6665


User avatar
0
MellowoodMedical created

Hi, I'm developing a Plugin Module as separate asembly and here is the project structure.

here is the full exception:
Castle.MicroKernel.Handlers.HandlerException
  HResult=0x80131500
  Message=Can't create component 'PatientPortal.PatientStripePayment.StripePatientPaymentAppService' as it has dependencies to be satisfied.

'PatientPortal.PatientStripePayment.StripePatientPaymentAppService' is waiting for the following dependencies:
- Service 'Abp.Domain.Repositories.IRepository`2[[PatientPortal.PatientStripePayment.Entities.Payment, PatientPortal.PatientStripePayment, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Guid, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]' which was not registered.
- Service 'Abp.Domain.Repositories.IRepository`2[[PatientPortal.PatientStripePayment.Entities.Invoice, PatientPortal.PatientStripePayment, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Guid, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]' which was not registered.

  Source=Castle.Windsor
  StackTrace:
   at Castle.MicroKernel.Handlers.DefaultHandler.AssertNotWaitingForDependency()
   at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden)
   at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired)
   at Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy, Boolean ignoreParentContext)
   at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy, Boolean ignoreParentContext)
   at Castle.MicroKernel.DefaultKernel.Resolve(Type service, IDictionary arguments)
   at Abp.Modules.AbpModuleManager.CreateModules(ICollection`1 moduleTypes, List`1 plugInModuleTypes)
   at Abp.Modules.AbpModuleManager.LoadAllModules()
   at Abp.AbpBootstrapper.Initialize()
   at Abp.AspNetCore.AbpApplicationBuilderExtensions.InitializeAbp(IApplicationBuilder app)
   at Abp.AspNetCore.AbpApplicationBuilderExtensions.UseAbp(IApplicationBuilder app, Action`1 optionsAction)
   at PatientPortal.Web.Startup.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) in C:\Users\serge\Source\Repos\Ideas Patient Portal v2.0\src\PatientPortal.Web.Host\Startup\Startup.cs:line 154

here is the source code:

using Stripe;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Castle.Core.Logging;
using Abp.Application.Services;
using Abp.Domain.Repositories;
using Abp.UI;
using Abp.Modules;
using System.Reflection;
using Abp.Zero;

namespace PatientPortal.PatientStripePayment
{
    [DependsOn(typeof(AbpZeroCoreModule))]
    public class StripePatientPaymentAppService : AbpModule, IApplicationService, IStripePatientPaymentAppService
    {
        private readonly IRepository<Entities.PatientPayment, Guid> _paymentRepository;

        private readonly IRepository<Entities.PatientInvoice, Guid> _invoiceRepository;

        public StripePatientPaymentAppService(IRepository<Entities.PatientPayment, Guid> paymentRepository,
            IRepository<Entities.PatientInvoice, Guid> invoiceRepository)
        {
            Logger = NullLogger.Instance;
            _paymentRepository = paymentRepository;
            _invoiceRepository = invoiceRepository;

        }


        public override void Initialize()
        {
            IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
        }


        public override void PostInitialize()
        {
            var paymentService = IocManager.Resolve<IStripePatientPaymentAppService>();
        }

        public async Task<string> CreateCharge(long amount, string currency, string invoiceId,
                                                string patientAcuID, string description,
                                                string token, string patientId = "")
        {
            // CheckPermission();
            StripeConfiguration.SetApiKey("sk_test_ktjohPHzIy5vsWJezVIUTq8m");

            var options = new ChargeCreateOptions
            {
                Amount = amount,
                Currency = currency, //"cad"
                Description = description,
                SourceId = token // obtained with Stripe.js,

            };
            var service = new ChargeService();
            Charge charge;
            try
            {
                Logger.Debug(string.Format("Creating Charge of {0} {1} with Stripe ", amount, currency));
                charge = await service.CreateAsync(options);


                var resPayment = await _paymentRepository.InsertAndGetIdAsync(new Entities.PatientPayment()
                {
                    //TODO CreatorUserId = AbpSession.UserId,
                    InvoiceId = invoiceId,
                    Amount = charge.Amount,
                    Currency = charge.Currency,
                    FailureCode = charge.FailureCode,
                    FailureMessage = charge.FailureMessage,
                    Paid = charge.Paid,
                    Status = charge.Status,
                    PatientID = patientId,
                    PatientAcuID = patientAcuID,
                    PaymentId = charge.Id
                });

                Entities.PatientInvoice invoiceUpdate = await _invoiceRepository.FirstOrDefaultAsync(i => i.InvoiceId == invoiceId);
                if (invoiceUpdate != null)
                {
                    invoiceUpdate.PaidDate = charge.Created;
                    var resInvoice = await _invoiceRepository.UpdateAsync(invoiceUpdate);
                }
                else
                {
                    //invoice wasn't found
                    Logger.Warn(string.Format("Payment has been made for invoice {0} PatientId {1} PatientAcuId {2} but the invoice was not found.", invoiceId, patientId, patientAcuID));
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
                throw new UserFriendlyException("Stripe Payment call has failed.", ex);
            }


            return charge.Id;
        }

        public async Task<IList<Entities.PatientPayment>> GetPayments()
        {
            return await _paymentRepository.GetAllListAsync(r => r.IsLedgerUpdated == false);
        }

        public async Task ConfirmLedgerUpdate(Guid transactionId)
        {
            var paymentTrx = await _paymentRepository.FirstOrDefaultAsync(r => r.Id == transactionId);
            if (paymentTrx != null && !paymentTrx.IsLedgerUpdated)
            {
                paymentTrx.IsLedgerUpdated = true;
                paymentTrx.LedgerUpdateDate = DateTime.Now;
            }
            else
            {
                throw new UserFriendlyException(string.Format("Transaction  ID {0} was not found or already synced with patient's ledger.", transactionId));
            }

        }


        /// <summary>
        /// g
        /// </summary>
        /// <param name="patientId"></param>
        /// <param name="invoiceId"></param>
        /// <param name="invoiceDate"></param>
        /// <param name="debit"></param>
        /// <param name="credit"></param>
        /// <param name="balance"></param>
        /// <param name="currency">ASCII code of currency symbol </param>
        /// <returns></returns>

        public async Task<Entities.PatientInvoice> CreateInvoice(string patientId, string patientAcuId, string invoiceId, DateTime invoiceDate, double debit, double credit, double balance, int currency)
        {
            Entities.PatientInvoice newInvoice = new Entities.PatientInvoice()
            {
                PatientID = patientId,
                PatientAcuID = patientAcuId,
                InvoiceDate = invoiceDate,
                InvoiceId = invoiceId,
                Debit = debit,
                Credit = credit,
                Balance = balance,
                Currency = currency
            };

            try
            {
                return await _invoiceRepository.InsertAsync(newInvoice);
            }
            catch (Exception ex)
            {

                throw new UserFriendlyException(ex.Message);
            }



        }
        /// <summary>
        /// Updates date,credit, debit,balance of existing invoice. 
        /// </summary>
        /// <param name="patientId"></param>
        /// <param name="invoiceId"></param>
        /// <param name="invoiceDate"></param>
        /// <param name="debit"></param>
        /// <param name="credit"></param>
        /// <param name="balance"></param>
        /// <returns></returns>
        public async Task<Entities.PatientInvoice> UpdateInvoice(string patientId,
                            string invoiceId, DateTime invoiceDate, double debit,
                            double credit, double balance, DateTime paidDate)
        {
            Entities.PatientInvoice existingInvoice = await _invoiceRepository.FirstOrDefaultAsync(r => r.InvoiceId == invoiceId && r.PatientID == patientId);

            if (existingInvoice == null)
                throw new UserFriendlyException(String.Format("No invoice with Id ={0} for patient with Id {1} was found", invoiceId, patientId));

            else
            {
                existingInvoice.InvoiceDate = invoiceDate;
                existingInvoice.Debit = debit;
                existingInvoice.Credit = credit;
                existingInvoice.Balance = balance;
                existingInvoice.PaidDate = paidDate;

                return await _invoiceRepository.UpdateAsync(existingInvoice);
            }
        }
        /// <summary>
        /// Soft deletes an invoice
        /// </summary>
        /// <param name="invoiceId"></param>
        /// <param name="patientId"></param>
        /// <returns></returns>
        public async Task DeleteInvoice(string patientId, string invoiceId)
        {
            var invoice = await _invoiceRepository.FirstOrDefaultAsync(p => p.InvoiceId == invoiceId && p.PatientID == patientId);

            if (invoice != null && !invoice.IsDeleted)
                await _invoiceRepository.DeleteAsync(invoice.Id);
            else
            {
                new UserFriendlyException(String.Format("No invoice with Id ={0} for patient with Id {1} was found", invoiceId, patientId));
            }

        }

        /// <summary>
        /// Gets all unpaid invoices for a patient
        /// </summary>
        /// <param name="patientId"></param>
        /// <returns></returns>
        public async Task<IList<Entities.PatientInvoice>> GetInvoices(string patientId)
        {

            return await _invoiceRepository.GetAllListAsync(r => r.PatientID == patientId
                                                                && r.PaidDate <= DateTime.MinValue
                                                                && r.IsDeleted == false);


        }


    }
}

3 Answer(s)
  • User Avatar
    1
    maliming created
    Support Team

    There is no db context in your PatientPortal.PatientStripePayment. IRepository will not be registered.

    Module classes and service classes are best implemented separately.

  • User Avatar
    0
    MellowoodMedical created

    Got it. Thank you. Woud it be possible to see an example of a service implemented as a plugin module including UI navigation?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @MellowoodMedical

    Unfortunately, there is no sample for plugin module including UI, sorry.