I'm having trouble hooking Unleash up in IServiceCollection. We're trying to use the DI IDisposable BeginScope() to store an IUnleashContextProvider backed by a Dictionary<string, string> as opposed to relying on HttpContext.Current.Items as in the README. The reason is b/c we use the scope pattern outside of ASP.NET Core and would like to be able to use the same Unleash boilerplate code regardless of whether we're in an ASP.NET Core app, a generic host builder, or a simple console app (creating a scope per ASP.NET request, MQ message received, timer interval, etc.).
This almost works, except that the IUnleashContextProvider is a property on the UnleashSettings class. IUnleash is registered as a singleton (per the docs), IUnleashContextProvider is registered as Scoped (also recommended in the docs and critical to capture request/message/etc-specific scope). UnleashSettings is registered as a singleton.
When ASPNETCORE_ENVIRONMENT=development, IServiceCollection.BuildServiceProvider(true) is called by the framework, which ensures that we're not capturing scoped/transient dependencies in a singleton. As far as I can tell it's unavoidable given the current architecture... I tried (see here: https://github.com/scottt732/UnleashClientTests/tree/master/UnleashClientTests).
DefaultUnleash(singleton) -> UnleashSettings(singleton) -> UnleashContextProvider(necessarily scoped, effectively captured) = invalid (single state would be shared across requests/race conditions).
The example code in the README ~gets around this issue by effectively having the UnleashContextProvider as a singleton which refers to HttpContext.Current?.Items. It will happen to be there in an ASP.NET request because your BeginRequest handler puts it there, but this requires using a static for state and breaks the ability for the same configuration to work in different application types.
I'm having trouble hooking Unleash up in
IServiceCollection
. We're trying to use the DIIDisposable BeginScope()
to store anIUnleashContextProvider
backed by aDictionary<string, string>
as opposed to relying onHttpContext.Current.Items
as in the README. The reason is b/c we use the scope pattern outside of ASP.NET Core and would like to be able to use the same Unleash boilerplate code regardless of whether we're in an ASP.NET Core app, a generic host builder, or a simple console app (creating a scope per ASP.NET request, MQ message received, timer interval, etc.).This almost works, except that the
IUnleashContextProvider
is a property on theUnleashSettings
class.IUnleash
is registered as a singleton (per the docs),IUnleashContextProvider
is registered as Scoped (also recommended in the docs and critical to capture request/message/etc-specific scope).UnleashSettings
is registered as a singleton.When
ASPNETCORE_ENVIRONMENT=development
,IServiceCollection.BuildServiceProvider(true)
is called by the framework, which ensures that we're not capturing scoped/transient dependencies in a singleton. As far as I can tell it's unavoidable given the current architecture... I tried (see here: https://github.com/scottt732/UnleashClientTests/tree/master/UnleashClientTests).DefaultUnleash(singleton) -> UnleashSettings(singleton) -> UnleashContextProvider(necessarily scoped, effectively captured) = invalid (single state would be shared across requests/race conditions).
The example code in the README ~gets around this issue by effectively having the
UnleashContextProvider
as a singleton which refers toHttpContext.Current?.Items
. It will happen to be there in an ASP.NET request because yourBeginRequest
handler puts it there, but this requires using a static for state and breaks the ability for the same configuration to work in different application types.