Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Alexsixcent opened this issue Aug 18, 2021 · 2 comments · Fixed by #753
Closed

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

Alexsixcent opened this issue Aug 18, 2021 · 2 comments · Fixed by #753

Comments

@Alexsixcent
Copy link

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.

@ChrisPulman
Copy link
Member

Thankyou for raising this issue, we will take a look into this as soon as possible. The provision of the Repo will help greatly.

ChrisPulman added a commit that referenced this issue Aug 18, 2021
fix for #752 Keyed instances can only have a single instance so keep latest
@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 23, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants