mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-04 18:09:12 +03:00
[PR #4966] [CLOSED] Repeated class creation due to manual creation of DI classes. #10346
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/jellyfin/jellyfin/pull/4966
Author: @BaronGreenback
Created: 1/6/2021
Status: ❌ Closed
Base:
master← Head:DI_IServerEntryPoint📝 Commits (1)
bce04c7Update ApplicationHost.cs📊 Changes
1 file changed (+13 additions, -0 deletions)
View changed files
📝
Emby.Server.Implementations/ApplicationHost.cs(+13 -0)📄 Description
Issue:
Example:
Plugin registers a class with DI.
eg. serviceCollection.AddSingleton<IDlnaServerManager, DlnaServerManager>();
Plugin implements the interface IServerEntryPoint so that the class with be instantiated and auto-started.
eg. public class DlnaServerManager : IDlnaServerManager, IServerEntryPoint
ApplicationHost calls GetExports(); which creates instances of the classes.
However, this creation is outside of DI, so when a class requiring another IDnlaServerManager parameter is encountered, another DlnaServerManager instance is created.
As DlnaServerManager is the parameter passed into CreateInstanceSafe a direct DI Resolve<> won't work, as our style is to use interfaces, not classes (serviceCollection.AddSingleton<IDlnaServerManager, DlnaServerManager> not serviceCollection.AddSingleton).
This solution - looks for an interface starting with I that matches the name of the class being asked to be created eg. Hello, would cause IHello to be used. DI is then queried to see if this interface / class has been registered, and then is asked to create the instance for us.
This should stop any instance being repeatedly created if it's been registered in DI - as long as it meets this criteria.
Why is it needed?
Cannot think of another way which IServerEntryPoint can be used with DI when code isn't triggered.
Concrete values are created using ActivatorUtilities.CreateInstance(ServiceProvider, type) which although permits DI parameters, does not feed the instance back into DI, so multiple calls to the function will result in multiple instances even thought it's registered in the DI as a singleton.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.