Skip to content

DI Considerations #1874

@dazinator

Description

@dazinator

Describe the bug
Hello!,
If I am reading the following code correctly, I think this could be a bug:

https://github.com/MarimerLLC/csla/blob/master/Source/Csla.Shared/ApplicationContext.cs#L861

In the case that a scope is not present in local context, a new scope is created and added. However I can't see that the scope ever gets disposed. Due to this, if there are any services resolved via this scope that are transient and implement IDisposable (i.e this would mean HttpClient being registered as transient, or an @Inject'ed paramater happening to be a transient IDisposable, those instances will build up over time in this DI scopes internal "tracking" list (it keeps track of transient disposables), they won't be ever be released until the scope is disposed. This could result in memory usage growing over time.

I think this is solved relatively easily (as per some of the things we have discussed already) and I am happy to submit a PR:

  • CSLA to allow a scoped IServiceProvider to be set in local context (rather than an IServiceScope as currently)
    • Caller is responsible for creating a DI Scope to begin with, and giving CSLA its IServiceProvider
    • Caller can do this at the start of a request by setting CSLA's scoped IServiceProvider from HttpContext.RequestServices (which gets disposed at the end of the request). In background jobs, user would create a new IServiceScope, set the CSLA IServiceProvider to that scopes IServiceProvider, then the caller would hang on to the service scope and dispose of it at the appropriate time (for example after the job had finished etc).

I noted that certain code allows the scoped provider to be null, and will work by reverting to ordinary type activation (non DI):

https://github.com/MarimerLLC/csla/blob/master/Source/Csla.Shared/Server/ObjectFactoryLoader.cs#L57

However with the following code, it looks like for an injectable method, do you think it would be desirable perhaps to throw an exception if the service provider was null, and injectable parameters were encountered - rather than injecting null parameters (which I am guessing is what happens in that case but I could be wrong - in fact as scoped IServiceProvider is currently created by CSLA on the fly if it doesn't exist, this should never be the case currently)

https://github.com/MarimerLLC/csla/blob/master/Source/Csla.Shared/Reflection/ServiceProviderMethodCaller.cs#L413

Would you be up for me submitting a PR with some discreet changes, for consideration?

Version and Platform
CSLA version: master branch
OS: Windows, Linux, iOS, Android, etc.
Platform: WinForms, WPF, ASP.NET Core, MVC, Xamarin, etc.

Code that Fails
Provide the failing code, ideally an isolated repro of the issue you are encountering.

Stack Trace or Exception Detail
Provide a stack trace, or at least detailed information about the exception.

Additional context
Add any other context about the problem here.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions