Skip to content

[BUG] UseDryIocDependencyResolver() throws container exception with Akavache #752

@Alexsixcent

Description

@Alexsixcent

Describe the bug
Calling UseDryIocDependencyResolver() with Akavache started throws this exception:
code: Error.UnableToRegisterDuplicateKey; message: Unable to register service with duplicate key 'Akavache.IBlobCache': (Akavache.IBlobCache, LocalMachine) There is already registered service with the same key {FactoryID=149, ImplType=Akavache.InMemoryBlobCache, Reuse=Singleton {Lifespan=1000}}.

The problem seems to occur when Splat tries to initialize Akavache by calling InitializeAkavache() when the Locator is set.

Here is the call stack at the throwing statement (see attached screenshot) :

ImTools.Ref.Swap<DryIoc.Container.Registry>(ref DryIoc.Container.Registry value = {DryIoc.Container.Registry}, System.Func<DryIoc.Container.Registry, DryIoc.Container.Registry> getNewValue = {Method = {System.Reflection.RuntimeMethodInfo}}, int retryCountUntilThrow = 50) Line 2190
ImTools.Ref<DryIoc.Container.Registry>.Swap(System.Func<DryIoc.Container.Registry, DryIoc.Container.Registry> getNewValue = {Method = {System.Reflection.RuntimeMethodInfo}}) Line 2120
DryIoc.Container.UseInstance(System.Type serviceType = {Name = "IBlobCache" FullName = "Akavache.IBlobCache"}, object instance = {Akavache.Sqlite3.SqlRawPersistentBlobCache}, DryIoc.IfAlreadyRegistered ifAlreadyRegistered = AppendNewImplementation, bool preventDisposal = false, bool weaklyReferenced = false, object serviceKey = ({System.RuntimeType}, "LocalMachine")) Line 745
DryIoc.Registrator.UseInstance(DryIoc.IContainer c = {DryIoc.Container}, System.Type serviceType = {Name = "IBlobCache" FullName = "Akavache.IBlobCache"}, object instance = {Akavache.Sqlite3.SqlRawPersistentBlobCache}, DryIoc.IfAlreadyRegistered ifAlreadyRegistered = AppendNewImplementation, bool preventDisposal = false, bool weaklyReferenced = false, object serviceKey = ({System.RuntimeType}, "LocalMachine")) Line 7759
Splat.DryIoc.DryIocDependencyResolver.Register(System.Func<object> factory = {Method = {System.Reflection.RuntimeMethodInfo}}, System.Type serviceType = {Name = "IBlobCache" FullName = "Akavache.IBlobCache"}, string contract = "LocalMachine") Line 119
Akavache.Sqlite3.Registrations.Register(Splat.IMutableDependencyResolver resolver = {Splat.DryIoc.DryIocDependencyResolver}, Splat.IReadonlyDependencyResolver readonlyDependencyResolver = {Splat.DryIoc.DryIocDependencyResolver}) Line 61
Akavache.DependencyResolverMixin.InitializeAkavache(Splat.IMutableDependencyResolver resolver = {Splat.DryIoc.DryIocDependencyResolver}, Splat.IReadonlyDependencyResolver readonlyDependencyResolver = {Splat.DryIoc.DryIocDependencyResolver}) Line 71
Akavache.BlobCache..cctor.AnonymousMethod__9_0() Line 52
Splat.InternalLocator.SetLocator(Splat.IDependencyResolver dependencyResolver = {Splat.DryIoc.DryIocDependencyResolver}) Line 90
Splat.Locator.SetLocator(Splat.IDependencyResolver dependencyResolver = {Splat.DryIoc.DryIocDependencyResolver}) Line 50
Splat.DryIoc.SplatDryIocExtensions.UseDryIocDependencyResolver(DryIoc.IContainer container = {DryIoc.Container}) Line 20
SplatAkavacheInitExceptionRepro.Program.Main(string[] args = {string[0]}) Line 17

I investigated a little bit and it seems Akavache tries to register two singleton implementations of IBlobCache with the same key ({Akavache.IBlobCache}, "LocalMachine") in the DI container which causes the exception. DryIoc doesn't seem to be able to handle that specific case.
It first registers an IBlobCache from Akavache.Core and then another with the same key from Akavache.Sqlite3.
Note that the ISecureBlobCache registration will probably throw the same exception as they function the same way.

Steps To Reproduce

  1. Create a minimal console app.
  2. Add the Akavache, Splat and Splat.DryIoc packages to the project.
  3. Register the application in Akavache.
  4. Add a call to UseDryIocDependencyResolver().
  5. A DryIoc.ContainerException is thrown.

I made a basic repro project here that replicates the issue.

Expected behavior
Akavache initialize properly and is registered in the DryIoc DI Container without issue.

Screenshots
image
The exact line in DryIoc.Container where the exception is thrown

Environment(please complete the following information):

  • OS: Windows 11
  • Version: 22000
  • Device: Desktop

Additional context
Note that i managed to trigger this exception on an UWP project and console app, so this most likely isn't platform specific.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions