-
Notifications
You must be signed in to change notification settings - Fork 13
Fix compatibility issue with Reflex 14.3.0 #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,77 +1,112 @@ | ||||||
| #if UNISTATE_REFLEX_SUPPORT | ||||||
|
|
||||||
| using System; | ||||||
| using System.Collections.Generic; | ||||||
| using Reflex.Core; | ||||||
| using Reflex.Enums; | ||||||
| using Reflex.Resolvers; | ||||||
|
|
||||||
| namespace UniState | ||||||
| { | ||||||
| namespace UniState | ||||||
| { | ||||||
| public static class ReflexBuildExtensions | ||||||
| { | ||||||
| public static void AddStateMachine( | ||||||
| public static void RegisterStateMachine( | ||||||
| this ContainerBuilder builder, | ||||||
| Type stateMachineImplementation, | ||||||
| Type stateMachineContract) | ||||||
| { | ||||||
| AddStateMachineInternal(builder, stateMachineImplementation, stateMachineContract, Lifetime.Transient); | ||||||
| RegisterStateMachine(builder, stateMachineImplementation, stateMachineContract, Lifetime.Transient); | ||||||
| } | ||||||
| public static void AddSingletonStateMachine( | ||||||
|
|
||||||
| public static void RegisterStateMachine( | ||||||
| this ContainerBuilder builder, | ||||||
| Type stateMachineImplementation, | ||||||
| Type stateMachineContract) | ||||||
| Type stateMachineContract, | ||||||
| Lifetime lifetime) | ||||||
| { | ||||||
| AddStateMachineInternal(builder, stateMachineImplementation, stateMachineContract, Lifetime.Singleton); | ||||||
| RegisterStateMachineInternal(builder, stateMachineImplementation, stateMachineContract, lifetime); | ||||||
| } | ||||||
|
|
||||||
| public static void AddState(this ContainerBuilder builder, Type state) | ||||||
|
|
||||||
| public static void RegisterState(this ContainerBuilder builder, Type state) | ||||||
| { | ||||||
| RegisterState(builder, state, Lifetime.Transient); | ||||||
| } | ||||||
|
|
||||||
| public static void RegisterState(this ContainerBuilder builder, Type state, Lifetime lifetime) | ||||||
| { | ||||||
| ValidateStateBindingInput(state); | ||||||
|
|
||||||
| builder.AddTransient(state, GetStateContracts(state)); | ||||||
| builder.RegisterType(state, GetStateContracts(state), lifetime, Resolution.Lazy); | ||||||
| } | ||||||
|
|
||||||
| public static void AddState(this ContainerBuilder builder, Type stateImplementation, Type stateContract) | ||||||
| { | ||||||
| ValidateStateBindingInput(stateImplementation, stateContract); | ||||||
|
|
||||||
| builder.AddTransient(stateImplementation, stateContract); | ||||||
| } | ||||||
|
|
||||||
| public static void AddSingletonState(this ContainerBuilder builder, Type state) | ||||||
|
|
||||||
| public static void RegisterState(this ContainerBuilder builder, Type stateImplementation, Type stateContract) | ||||||
| { | ||||||
| ValidateStateBindingInput(state); | ||||||
| RegisterState(builder, stateImplementation, stateContract, Lifetime.Transient); | ||||||
| } | ||||||
|
|
||||||
| public static void RegisterState( | ||||||
| this ContainerBuilder builder, | ||||||
| Type stateImplementation, | ||||||
| Type stateContract, | ||||||
| Lifetime lifetime) | ||||||
| { | ||||||
| ValidateStateBindingInput(stateImplementation, stateContract); | ||||||
|
|
||||||
| builder.AddSingleton(state, GetStateContracts(state)); | ||||||
| builder.RegisterType( | ||||||
| stateImplementation, | ||||||
| new[] { stateContract }, | ||||||
| lifetime, | ||||||
| Resolution.Lazy); | ||||||
| } | ||||||
|
|
||||||
| public static void AddSingletonState(this ContainerBuilder builder, Type stateImplementation, | ||||||
| Type stateContract) | ||||||
| { | ||||||
| ValidateStateBindingInput(stateImplementation, stateContract); | ||||||
|
|
||||||
| builder.AddSingleton(stateImplementation, stateContract); | ||||||
| } | ||||||
|
|
||||||
| [Obsolete("Use RegisterStateMachine(builder, implementation, contract) or the overload with Lifetime.")] | ||||||
| public static void AddStateMachine( | ||||||
| this ContainerBuilder builder, | ||||||
| Type stateMachineImplementation, | ||||||
| Type stateMachineContract) => | ||||||
| RegisterStateMachine(builder, stateMachineImplementation, stateMachineContract); | ||||||
|
|
||||||
| [Obsolete("Use RegisterStateMachine(builder, implementation, contract, Lifetime.Singleton) instead.")] | ||||||
| public static void AddSingletonStateMachine( | ||||||
| this ContainerBuilder builder, | ||||||
| Type stateMachineImplementation, | ||||||
| Type stateMachineContract) => | ||||||
| RegisterStateMachine(builder, stateMachineImplementation, stateMachineContract, Lifetime.Singleton); | ||||||
|
|
||||||
| [Obsolete("Use RegisterState(builder, state) or the overload with Lifetime.")] | ||||||
| public static void AddState(this ContainerBuilder builder, Type state) => | ||||||
| RegisterState(builder, state); | ||||||
|
|
||||||
| [Obsolete("Use RegisterState(builder, implementation, contract) or the overload with Lifetime.")] | ||||||
| public static void AddState(this ContainerBuilder builder, Type stateImplementation, Type stateContract) => | ||||||
| RegisterState(builder, stateImplementation, stateContract); | ||||||
|
|
||||||
| [Obsolete("Use RegisterState(builder, state, Lifetime.Singleton) instead.")] | ||||||
| public static void AddSingletonState(this ContainerBuilder builder, Type state) => | ||||||
| RegisterState(builder, state, Lifetime.Singleton); | ||||||
|
|
||||||
| [Obsolete("Use RegisterState(builder, implementation, contract, Lifetime.Singleton) instead.")] | ||||||
| public static void AddSingletonState( | ||||||
| this ContainerBuilder builder, | ||||||
| Type stateImplementation, | ||||||
| Type stateContract) => | ||||||
| RegisterState(builder, stateImplementation, stateContract, Lifetime.Singleton); | ||||||
|
|
||||||
| private static void ValidateStateBindingInput(Type stateImplementation, Type stateContract) | ||||||
| { | ||||||
| ValidateStateBindingInput(stateImplementation); | ||||||
|
|
||||||
| if (!stateContract.IsAssignableFrom(stateImplementation)) | ||||||
| { | ||||||
| throw new ArgumentException( | ||||||
| $"AddState({stateImplementation.Name}): Type parameter state must implement {stateContract.Name}."); | ||||||
| } | ||||||
| } | ||||||
| if (!stateContract.IsAssignableFrom(stateImplementation)) | ||||||
| { | ||||||
| throw new ArgumentException( | ||||||
| $"RegisterState({stateImplementation.Name}): Type parameter state must implement {stateContract.Name}."); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| private static void ValidateStateBindingInput(Type state) | ||||||
| { | ||||||
| if (!typeof(IExecutableState).IsAssignableFrom(state)) | ||||||
| { | ||||||
| throw new ArgumentException( | ||||||
| $"AddState({state.Name}): Type parameter state must implement IState<TPayload>"); | ||||||
| $"RegisterState({state.Name}): Type parameter state must implement IState<TPayload>"); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -91,93 +126,48 @@ private static Type[] GetStateContracts(Type state) | |||||
|
|
||||||
| private static void ValidateStateMachineBindingInput(Type stateMachineImplementation, Type stateMachineContract) | ||||||
| { | ||||||
| if (stateMachineImplementation == stateMachineContract) | ||||||
| { | ||||||
| throw new ArgumentException( | ||||||
| $"AddStateMachine<{stateMachineImplementation.Name}>: Type parameters must differ : " + | ||||||
| "use AddStateMachine() where stateMachineImplementation implements stateMachineContract.\");"); | ||||||
| } | ||||||
|
|
||||||
| if (!stateMachineContract.IsAssignableFrom(stateMachineImplementation)) | ||||||
| { | ||||||
| throw new ArgumentException( | ||||||
| $"AddStateMachine: Type {stateMachineImplementation.Name} " + | ||||||
| $"must implement {stateMachineContract.Name}."); | ||||||
| } | ||||||
|
|
||||||
| if (!typeof(IStateMachine).IsAssignableFrom(stateMachineContract)) | ||||||
| { | ||||||
| throw new ArgumentException( | ||||||
| $"AddStateMachine: Type {stateMachineContract.Name} " + | ||||||
| $"must implement IStateMachine."); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| private static void AddStateMachineInternal( | ||||||
| ContainerBuilder builder, | ||||||
| Type stateMachineImplementation, | ||||||
| Type stateMachineContract, | ||||||
| Lifetime lifetime) | ||||||
| { | ||||||
| ValidateStateMachineBindingInput(stateMachineImplementation, stateMachineContract); | ||||||
|
|
||||||
| builder.Bindings.Add(Binding.Validated( | ||||||
| new ReflexStateMachineResolver(stateMachineImplementation, lifetime), | ||||||
| stateMachineImplementation, | ||||||
| stateMachineImplementation, | ||||||
| stateMachineContract)); | ||||||
| } | ||||||
|
|
||||||
| private sealed class ReflexStateMachineResolver : IResolver | ||||||
| { | ||||||
| private readonly Type _stateMachineImplementation; | ||||||
| private readonly Lifetime _lifetime; | ||||||
| private readonly List<IDisposable> _disposables = new(); | ||||||
|
|
||||||
| private object _instance; | ||||||
|
|
||||||
| public Lifetime Lifetime => _lifetime; | ||||||
|
|
||||||
| public ReflexStateMachineResolver(Type stateMachineImplementation, Lifetime lifetime) | ||||||
| if (stateMachineImplementation == stateMachineContract) | ||||||
| { | ||||||
| _stateMachineImplementation = stateMachineImplementation; | ||||||
| _lifetime = lifetime; | ||||||
| throw new ArgumentException( | ||||||
| $"RegisterStateMachine<{stateMachineImplementation.Name}>: Type parameters must differ : " + | ||||||
| "use RegisterStateMachine() where stateMachineImplementation implements stateMachineContract.\");"); | ||||||
|
||||||
| "use RegisterStateMachine() where stateMachineImplementation implements stateMachineContract.\");"); | |
| "use RegisterStateMachine() where stateMachineImplementation implements stateMachineContract."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ValidateStateBindingInput(Type state)checksIExecutableState, but the thrown message says the type must implementIState<TPayload>. Since non-IState<TPayload>types can still be validIExecutableState(e.g., sub-state containers), the message is misleading—update it to referenceIExecutableState(or whatever the actual required contract is).