[PR #4966] [CLOSED] Repeated class creation due to manual creation of DI classes. #10346

Closed
opened 2026-02-07 06:18:38 +03:00 by OVERLORD · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/jellyfin/jellyfin/pull/4966
Author: @BaronGreenback
Created: 1/6/2021
Status: Closed

Base: masterHead: DI_IServerEntryPoint


📝 Commits (1)

  • bce04c7 Update ApplicationHost.cs

📊 Changes

1 file changed (+13 additions, -0 deletions)

View changed files

📝 Emby.Server.Implementations/ApplicationHost.cs (+13 -0)

📄 Description

Issue:

  1. Register class with DI.
  2. Class is manually instantiated via the GetExports
  3. DI will create another instance of class as the creation is outside of DI, and cannot be injected into it.

Example:

  1. Plugin registers a class with DI.
    eg. serviceCollection.AddSingleton<IDlnaServerManager, DlnaServerManager>();

  2. Plugin implements the interface IServerEntryPoint so that the class with be instantiated and auto-started.
    eg. public class DlnaServerManager : IDlnaServerManager, IServerEntryPoint

  3. 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.

## 📋 Pull Request Information **Original PR:** https://github.com/jellyfin/jellyfin/pull/4966 **Author:** [@BaronGreenback](https://github.com/BaronGreenback) **Created:** 1/6/2021 **Status:** ❌ Closed **Base:** `master` ← **Head:** `DI_IServerEntryPoint` --- ### 📝 Commits (1) - [`bce04c7`](https://github.com/jellyfin/jellyfin/commit/bce04c7ba09ab5630aa725e53095d306aa25b083) Update ApplicationHost.cs ### 📊 Changes **1 file changed** (+13 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `Emby.Server.Implementations/ApplicationHost.cs` (+13 -0) </details> ### 📄 Description **Issue:** 1. Register class with DI. 2. Class is manually instantiated via the _GetExports<T>_ 3. DI will create another instance of class as the creation is outside of DI, and cannot be injected into it. **Example:** 1. Plugin registers a class with DI. _eg. serviceCollection.AddSingleton<IDlnaServerManager, DlnaServerManager>();_ 2. Plugin implements the interface _IServerEntryPoint_ so that the class with be instantiated and auto-started. _eg. public class DlnaServerManager : IDlnaServerManager, IServerEntryPoint_ 3. ApplicationHost calls _GetExports<IServerEntryPoint>();_ 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<DlnaServerManager>). 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. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
OVERLORD added the pull-request label 2026-02-07 06:18:38 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/jellyfin#10346