Class AchievementSignalSubscriptionBinder
Connects an AchievementEvaluator to the dispatcher: resolves every signal type name the authored conditions listen for and subscribes to each distinct one exactly once, routing what arrives into the evaluator.
Implements
Inherited Members
Namespace: Serenity.Achievements.Infrastructure.Services
Assembly: Serenity.Achievements.Infrastructure.dll
Syntax
public class AchievementSignalSubscriptionBinder : IDisposable
Remarks
Subscription is by closed generic, which a name in a serialized field cannot express, so the
open generic Subscribe<T>(EventDispatcherSignalDelegate) is cached once and closed per
resolved type — the technique SignalReactionComponent uses for the same reason.
Engine-free, and never throws outward: a name that no longer resolves is reported once and skipped, so one renamed signal cannot take the other ninety-nine achievements down with it, and a failing evaluation is contained here as well as inside the evaluator, so nothing an achievement does can propagate into the dispatcher and break its other subscribers.
Constructors
AchievementSignalSubscriptionBinder(IEventDispatcherService, AchievementEvaluator, ILogService, Func<string, Type>)
Initializes a new instance of the AchievementSignalSubscriptionBinder class.
Declaration
public AchievementSignalSubscriptionBinder(IEventDispatcherService eventDispatcherService, AchievementEvaluator evaluator, ILogService logService, Func<string, Type> resolveSignalType = null)
Parameters
| Type | Name | Description |
|---|---|---|
| IEventDispatcherService | eventDispatcherService | The dispatcher to subscribe on. |
| AchievementEvaluator | evaluator | The evaluator every dispatched signal is routed into. |
| ILogService | logService | Logging service. May be |
| Func<string, Type> | resolveSignalType | Turns an authored name into a type. Defaults to ResolveType(string), which is what a project wants; a caller supplies its own only to bind against types the loaded assemblies do not carry. |
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | Thrown when a required collaborator is |
Properties
SubscribedSignalTypes
The signal types this binder is currently subscribed to.
Declaration
public IReadOnlyList<Type> SubscribedSignalTypes { get; }
Property Value
| Type | Description |
|---|---|
| IReadOnlyList<Type> |
UnresolvedSignalTypeNames
The authored names that did not resolve to a usable signal type.
Declaration
public IReadOnlyList<string> UnresolvedSignalTypeNames { get; }
Property Value
| Type | Description |
|---|---|
| IReadOnlyList<string> |
Methods
Bind()
Subscribes to every signal type the evaluator's conditions listen for.
Declaration
public IDisposable Bind()
Returns
| Type | Description |
|---|---|
| IDisposable | A handle that unsubscribes everything when disposed. |
Remarks
Idempotent: a type already subscribed is left exactly as it is.
Dispose()
Unsubscribes every subscription this binder made. Safe to call more than once.
Declaration
public void Dispose()
Rebind()
Retries only the names that did not resolve last time, leaving every existing subscription untouched.
Declaration
public int Rebind()
Returns
| Type | Description |
|---|---|
| int | How many new signal types were subscribed to. |
Remarks
A signal type can arrive after the binder ran: an assembly loaded on demand, a scene that
pulls in an addressable, a mod. PR 3's runner calls this on the same backoff timer it
uses for IAchievementService.RetryPlatformSyncAsync, and it costs nothing once
every name has resolved.