简体   繁体   中英

Typhoon: Injecting run-time arguments into a singleton

I'm trying to figure out how to inject run-time arguments into a singleton when it is created, and then have those arguments just be remembered from then on. I'm not sure if the interface for run-time arguments can support this, though. Say, for example, I have a Client object that requires a token, and has the following initializer:

+ (instancetype)initWithToken:(NSString *)token;

The token is obtained at runtime from the server and is different for every user, so I can't simply put the NSString in the definition. So I create the following method on my Typhoon assembly:

- (Client *)clientWithToken:(NSString *)token;

However, in the future (when I'm injecting this client into other classes), I won't have the token on hand to call this method with. So I would like to just be able to inject [self client] , for example. Since the client is a singleton and has already been created, the token isn't necessary, anyway.

However, I can't seem to find a way to do this. Obviously, defining a separate method called client would just return a different client. Can I just call clientWithToken:nil and the argument will be ignored if the client already exists? Perhaps traversing the assembly's singletons array would work, but that is obviously very inelegant.

I have considered injecting by type (so I don't need a method to call), but I have multiple different clients of the same type, so I need to be explicit about which client to inject. Of course, there is also the option of removing this parameter from the initializer, and instead setting it as a property from outside the assembly; however this pattern is used throughout our application, so I would like to avoid rewriting that much code.

Thank you.

Reviewing the Typhoon User Guide's ' When to Use Runtime Arguments ' shows that this scenario isn't really a good match. Runtime arguments are great when we have a top-level component that mixes some static dependencies with information that is known later - thus avoiding the creation of a custom 'factory' class. Its not possible to use them in the way described.

Instead consider the following suggestions:

Inject a shared context class

Create a mutable Session model object and register it with Typhoon. Update the state on this model when you have a token. Inject this into the clients, which will use this session information when making connections.

Aspect Hook

Hook your clients so that before a method is invoked the token information is available. This could be done by:

  • Using an Aspects library like this one .
  • Define a Protocol for the clients and wrap the base implementation in one that is security aware.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM