Skip to content

Bind Injector to Itself #9

Closed
rodnaph opened this Issue Sep 22, 2011 · 4 comments

2 participants

@rodnaph
rodnaph commented Sep 22, 2011

Currently when you need to create objects that have dependencies you need to set and then get the global instance. ie, somewhere in my class i need to create another object...

- (void)someMethod {
  // first get the global instance
  JSObjectionInjector *injector = [JSObjection globalInjector];
  // then use the injector to create something.
  // NB: this is NOT a dependency
}

This reduces the injector to little more than a service locater. I think it would be more useful, and more testable, to allow the injector to itself be injected as a dependency. So if your class needs to create other objects you simply ask for the injector as one of your dependencies.

@interface MyClass
@property (nonatomic, retain) JSObjectionInjector *injector;
@end

@implementation MyClass

objection_register( MyClass );
objection_requires( @"injector" );

I am currently doing this through my own "Injector Provider", but I think it would be a good feature to have built in.

@dewind
dewind commented Sep 22, 2011

Yes, I've had to do this as well. Providing such a mechanism would be a good idea. I'm not entirely convinced that keeping a reference to the injector is the way to do it. Guice, ironically, has the idea of a Provider, that injects factories of certain types.

Obviously, Objective-C isn't strongly typed and doesn't use generics, so that exact implementation is unnecessary.

Perhaps this:

@interface MyClass
@property(nonatomic, retain) JSObjectFactory *factory
@end

@implementation MyClass
objection_register(MyClass)
objection_requires(@"factory")

- (void)myMethod {
  id object = [self.factory get:[SomeClass class]];
}
@end
@rodnaph
rodnaph commented Sep 23, 2011

Yes, injecting a factory would be the right thing to do if you needed to do some structured creation of objects, but when you just need to create objects that have dependencies you'd need to create essentially a one-line factory. Which is a bit annoying.

Factories are great and have their place, but you don't always need them.

No bother if you don't want to include this though, it's not exactly much work to do it yourself...

@implementation InjectorProvider
- (id)createInstance:(JSObjectionInjector *)context {
    return context;
}
@end

I was just thinking it would be pretty trivial to provide the injector as a dependency for the circumstances when it is useful.

@dewind
dewind commented Sep 23, 2011

I'm not suggesting that a factory needs to be created for each type. Instead, I'm suggesting that an object shouldn't need to be injector aware to fetch objects from the injection context. The Guice provider mechanism is exactly that, however, it isn't necessary to have a factory for each type.

@dewind dewind closed this Oct 25, 2011
@dewind
dewind commented Oct 25, 2011

Added the concept of an object factory. See README for more details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.