I guess I could make AddSingleton work for this if I add my own layer upon it that manually keeps data in memory mapped to the current session/circuit/whatever ID (along with manual GC), but I feel like this sorta defeats the point of DI. What are my options?
CodePudding user response:
You might just want to use the 'Session' to initialize a service scoped to your session. It is accessible in your controller methods.
Something like this
Session["MyService"] = new MyService();
CodePudding user response:
As you haven't provided much context here's how to get a scoped service container from the top level service provider that will create scoped and Transient services within the new container. This is how OwningComponentBase
does it (it lives for the lifetime of the component and gets correctly disposed when the component is destroyed):
[Inject] IServiceScopeFactory ScopeFactory { get; set; } = default!;
protected IServiceProvider ScopedServices
{
get
{
if (ScopeFactory == null)
throw new InvalidOperationException("Services cannot be accessed before the component is initialized.");
if (this.IsDisposed)
throw new ObjectDisposedException($"{this.GetType().Name}");
_scope ??= ScopeFactory.CreateAsyncScope();
return _scope.Value.ServiceProvider;
}
}
public TService GetService<TService>()
=> ScopedServices.GetRequiredService<TService>();
You do need to be careful about which instance
of scoped services you want to use/ are using.
You can also build your own service provider:
var services = new ServiceCollection();
// Adds the application services to the collection
......
// Creates a Service Provider from the Services collection
var provider = services.BuildServiceProvider();
// Get a service
var service = provider.GetService<TService>();
// Dispose of the provider
provider.Dispose();
provider = null;