0
votes

Please note that the issue I'm experiencing is NOT a generic "IndexOutOfRangeException", which I am well familiar with. The issue I am seeing is specific to the Unity DI container when using with an ASP.NET Web API back end, and occurs at random times.

I am using a Unity DI container within the context of an ASP.NET Web API back end written in C#. For the most part, the site works fine. However, at random times throughout the day, we are getting an HTTP 500 error code with the message "An error occurred when trying to create a controller of type 'MyController'. Make sure that the controller has a parameterless public constructor. .... Exception is: IndexOutOfRangeException - Index was outside the bounds of the array".

We've tried using IIS configuration to recycle the app pool on a regular basis, but we are still getting this error.

Here's my code

protected void Application_Start()
{
    GlobalConfiguration.Configure(WebApiConfig.Register);
    GlobalConfiguration.Configuration.EnableDependencyInjection();
    AreaRegistration.RegisterAllAreas();
    RouteConfig2.RegisterRoutes(RouteTable.Routes);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    UnityConfig.RegisterComponents();
}

public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = UnityDI.Containers.GetContainer();
        GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
    }
}


namespace UnityDI
{
    public static class Containers
    {
        public static UnityContainer GetContainer(bool staticDbFactory = false)
        {
            var container = new UnityContainer();

            //DbContext
            if (staticDbFactory)
                container.RegisterType<IDbContextFactory, DbContextFactory>(new ContainerControlledLifetimeManager());
            else
                container.RegisterType<IDbContextFactory, DbContextFactory>();

            //Services
            container.RegisterType<IAddressService, AddressService>();
            container.RegisterType<IAdminService, AdminService>();
            /* (other items omitted for brevity) */

            /* EdiFileProcessorBase registrations */
            container.RegisterType<EdiFileProcessorBase, AbcInboundBolFileProcessor>(EdiFileTypeEnum.AbcInboundBol.ToString());
            container.RegisterType<EdiFileProcessorBase, AbcInboundVesselStatusFileProcessor>(EdiFileTypeEnum.AbcInboundVesselStatus.ToString());
            return container;
        }
    }
}

[InjectionConstructor]
public DocumentService(
    IDbContextFactory dbContextFactory,
    IBlobStorageService blobStorageService,
    Lazy<IEmailService> emailService,
    Lazy<ILocationService> locationService,
    Lazy<IMailingService> mailService,
    Lazy<IOceanBookingService> oceanBookingService
    ) : base(dbContextFactory)
{
    _blobStorageService = blobStorageService;
    _emailService = emailService;
    _locationService = locationService;
    _mailService = mailService;
    _xmlHelper = new XMLHelper();
    _oceanBookingService = oceanBookingService;

    Aspose.Pdf.License license = new Aspose.Pdf.License();
    license.SetLicense("Aspose.Total.lic");
    license.Embedded = true;

    Aspose.Words.License wlicense = new Aspose.Words.License();
    wlicense.SetLicense("Aspose.Total.lic");
    Aspose.Cells.License clicense = new Aspose.Cells.License();
    clicense.SetLicense("Aspose.Total.lic");
}

Here's the full error message we're seeing.


> An error occurred when trying to create a controller of type
> 'MyController'. Make sure that the controller has a parameterless
> public constructor. Resolution of the dependency failed, type =
> "ACME.AcmeApp.API.Controllers.MyController", name = "(none)".
> Exception occurred while: Calling constructor
> ACME.AcmeApp.Services.Services.DocumentService(ACME.AcmeApp.DAL.Interfaces.IDbContextFactory
> dbContextFactory, ACME.AcmeApp.Services.Interfaces.IBlobStorageService
> blobStorageService,
> System.Lazy`1[[ACME.AcmeApp.Services.Interfaces.IEmailService,
> ACME.AcmeApp.Services, Version=1.0.0.0, Culture=neutral,
> PublicKeyToken=null]] emailService,
> System.Lazy`1[[ACME.AcmeApp.Services.Interfaces.ILocationService,
> ACME.AcmeApp.Services, Version=1.0.0.0, Culture=neutral,
> PublicKeyToken=null]] locationService,
> System.Lazy`1[[ACME.AcmeApp.Services.Interfaces.IMailingService,
> ACME.AcmeApp.Services, Version=1.0.0.0, Culture=neutral,
> PublicKeyToken=null]] mailService,
> System.Lazy`1[[ACME.AcmeApp.Services.Interfaces.IOceanBookingService,
> ACME.AcmeApp.Services, Version=1.0.0.0, Culture=neutral,
> PublicKeyToken=null]] oceanBookingService). Exception is:
> IndexOutOfRangeException - Index was outside the bounds of the array.
> ----------------------------------------------- At the time of the exception, the container was:
> 
>   Resolving ACME.AcmeApp.API.Controllers.MyController,(none)  
> Resolving parameter "documentService" of constructor
> ACME.AcmeApp.API.Controllers.MyController(ACME.AcmeApp.DAL.Interfaces.IDbContextFactory
> dbFactory, ACME.AcmeApp.Services.Interfaces.ISiService siService,
> ACME.AcmeApp.Services.Interfaces.IStorageService storageService,
> ACME.AcmeApp.Services.Services.IRepairService repairService,
> ACME.AcmeApp.Services.Interfaces.IDocumentService documentService,
> ACME.AcmeApp.Services.Interfaces.IImageService ImageService,
> ACME.AcmeApp.Services.Interfaces.INoteService noteService,
> ACME.AcmeApp.Services.Interfaces.IVisitService visitService,
> ACME.AcmeApp.Services.Interfaces.IOrderService orderService,
> ACME.AcmeApp.Services.Interfaces.IAuditService auditService,
> ACME.AcmeApp.Services.Interfaces.INotificationService
> notificationService, ACME.AcmeApp.Services.Interfaces.ILocationService
> locationService, ACME.AcmeApp.Services.ICustomerService
> customerSerivce, ACME.AcmeApp.Services.Interfaces.ICommonService
> commonService,
> System.Lazy`1[[ACME.AcmeApp.Services.Interfaces.ILegService,
> ACME.AcmeApp.Services, Version=1.0.0.0, Culture=neutral,
> PublicKeyToken=null]] legService)
>     Resolving ACME.AcmeApp.Services.Services.DocumentService,(none) (mapped from ACME.AcmeApp.Services.Interfaces.IDocumentService,
> (none))
>     Calling constructor ACME.AcmeApp.Services.Services.DocumentService(ACME.AcmeApp.DAL.Interfaces.IDbContextFactory
> dbContextFactory, ACME.AcmeApp.Services.Interfaces.IBlobStorageService
> blobStorageService,
> System.Lazy`1[[ACME.AcmeApp.Services.Interfaces.IEmailService,
> ACME.AcmeApp.Services, Version=1.0.0.0, Culture=neutral,
> PublicKeyToken=null]] emailService,
> System.Lazy`1[[ACME.AcmeApp.Services.Interfaces.ILocationService,
> ACME.AcmeApp.Services, Version=1.0.0.0, Culture=neutral,
> PublicKeyToken=null]] locationService,
> System.Lazy`1[[ACME.AcmeApp.Services.Interfaces.IMailingService,
> ACME.AcmeApp.Services, Version=1.0.0.0, Culture=neutral,
> PublicKeyToken=null]] mailService,
> System.Lazy`1[[ACME.AcmeApp.Services.Interfaces.IOceanBookingService,
> ACME.AcmeApp.Services, Version=1.0.0.0, Culture=neutral,
> PublicKeyToken=null]] oceanBookingService)  Index was outside the
> bounds of the array.

1
My question is not a duplicate. This is not a generic IndexOutOfRangeException, as the exception seems to be within Unity DI code, not code that I've written. My issue is specific to Unity DI.P.J.
Please remove the "marked as duplicate" tag.P.J.
Can you post the code inside the relevant constructor for ACME.AcmeApp.Services.Services.DocumentService?Jonas Høgh
I've added the code for the DocumentService constructor above.P.J.
Smells like a bug in the Aspose license initialization, such as the one this user is experiencing: forum.aspose.com/t/…Jonas Høgh

1 Answers

0
votes

I realize this isn't an answer as such, but I hope you can use it anyway, it's too long for a comment, so here goes:

I don't believe the error is related to Unity as such. Unity is telling you that the DocumentService constructor is throwing an exception. I would proceed with the following steps to investigate further:

  1. If possible, move all the Aspose license initialization code to a static method, and call it once at application startup time. There's no reason to waste time having Aspose look for license files over and over again
  2. Inject a logger into the documentservice, wrap the constructor body in a try/catch, and log the exception to your logger
  3. If there's anything interesting in the default constructor of XMLHelper, investigate this code as well. Since its constructed explicitly in the code rather than by Unity, this could also be the source of the error.