Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Support for optional Injection Points #10

Closed
Undistraction opened this Issue Sep 26, 2011 · 10 comments

Comments

Projects
None yet
2 participants

It would be very useful to have the option of marking requirements as optional. At the moment if a dependency is not satisfied Objection throws an exception, however it should be able to check whether the dependency was optional or not and suppress the exception if it was.

Contributor

thestoics commented Sep 28, 2011

I'd like to keep Objection's interface simple if I can. What kind of situation were you thinking of using this feature for?

It seems to me to be a fairly fundamental requirement to be honest. Some classes are used in many different places or with an application in different states, and without optional injection points this becomes limited. A class might be designed to have a dependency satisfied either when it is created or later during application flow. Or it might only be satisfied once a user has performed some action, for example I might instantiate a class using an injector every time my application is run. maybe the first few times it is run one of its dependencies is missing because a user hasn't filled out some details, but later on, after the use has filled out details, when the application initialises, that dependency is present and injected. I think this is a fundamental feature for making Objection more flexible. So far as the API goes I think this wouldn't involve many changes. You would just need a way for a dependency to be declared as optional. Changes behind the API would be another matter of course, but I think I can see how it could be done without too much fuss.

Contributor

thestoics commented Sep 28, 2011

Interesting,

Objection does provide a default instance if it is a class requirement. So this would be something needed for a protocol binding, correct?

Please can you clarify what you mean by 'Objection does provide a default instance if it is a class requirement'?

Contributor

thestoics commented Sep 28, 2011

The only time Objection throws an exception is if an object requires a dependency where the interface is not a class but rather a protocol.

@interface MyClass
@property (nonatomic, retain) id<AProtocol> object // Objection throws if a binding was not created
@property (nonatomic, retain) AnotherClass object2 // if AnotherClass is not registered. Objection will register it and provide an instance of it
@end

Ah. I hadn't noticed that. In fact I think this would be another good way of using an annotation and is tied into optional dependencies. Perhaps every dependency should support annotation with 'optional' and 'auto'. I would expect to be able to decide firstly if a dependency is optional and secondly if it isn't optional, whether Objection should satisfy it automatically. Satisfying a dependency automatically is a little confusing as a default I think. Perhaps I was planning on mapping a particular preconfigured instance of a class to a dependency but forgot. Now it will be confusing for me to see what is wrong as the dependency will have been satisfied, but not with the instance I was wanted to use.

Contributor

thestoics commented Sep 28, 2011

Agreed,

In order to support optional dependencies Objection would have to by default:

  • Throw regardless of whether it is a protocol or class -- be consistent
  • Suppress errors if the dependency is optional -- nil isn't an error so I dont see a need for providing a default instance.

Absolutely. Even without optional dependencies I think it is important to throw whether protocol or class, but I really think optional dependencies would be a really nice addition.

Contributor

thestoics commented Sep 28, 2011

I'll enqueue this feature request along with issues #11 and #9. Hopefully
we'll have something by next week.

That's great. If you are interested I've added a few simple methods to your JSObjection.h API here: https://github.com/1ndivisible/objection/blob/master/Source/JSObjection.m. Also found it very easy to make everything work within a single context by making a couple of chnages here: https://github.com/1ndivisible/objection/blob/master/Source/JSObjectionInjector.m by 1. passing bindings straight to the global context. 2. Removing a small block of functionality in getObject. Seems to be working fine. Might be worth considering implementing a way of choosing between a global mode and a separated injectors mode? Updated your tests to cover these changes I think.

@thestoics thestoics closed this Nov 30, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment