Skip to content
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

There is no way to inject an init parameter by type #96

Closed
ratkins opened this issue Nov 8, 2013 · 1 comment
Closed

There is no way to inject an init parameter by type #96

ratkins opened this issue Nov 8, 2013 · 1 comment

Comments

@ratkins
Copy link

ratkins commented Nov 8, 2013

If I'm injecting a property declared to hold an object conforming to a protocol I can do

- (id)homeScreenViewController
{
    return [TyphoonDefinition withClass:[HomeScreenViewController class] properties:^(TyphoonDefinition *definition) {
        [definition injectProperty:@selector(managedObjectContextFactory)];
    }];
}

... and my HomeScreenViewController's managedObjectContextFactory will be injected with whatever implementation of id<ManagedObjectContextFactory> Typhoon can find.

But if I instead have an object that would like to take an id<ManagedObjectContextFactory> as a parameter to its init method, I can't do that:

- (id)stubServerSentEventGenerator
{
    return [TyphoonDefinition withClass:[StubServerSentEventGenerator class] initialization:^(TyphoonInitializer *initializer) {
        initializer.selector = @selector(initWithManagedObjectContextFactory:);
    }];
}

It seems Typhoon simply passes in nil to the init method here, where it should be looking up and injecting whatever implementation of id<ManagedObjectContextFactory> it has. I can't add an [initializer injectWithDefinition:???]; because I don't have a reference to the assembly that defines the concrete ManagedObjectContextFactory—which could be different depending on what environment (and therefore composition of assemblies) I'm bringing up the container in.

@jasperblues
Copy link
Member

Thanks for reporting this. Unfortunately there is no possible solution!

The Objective-C run-time provides full type introspection for properties, however for initializers (or any other methods) its only possible to read whether a given parameter is a primitive (and what kind of primitive) or id type. .

Therefore, its necessary to explicitly declare the arguments that will be provided to an initializer.

You can inject either by reference or using Typhoon's type converter system (but you must declare the target type if non primitive).

Consider instead using a property if you need by-type injection. One of the advantages of initializer injection is that you can verify an object is in the required state, or do other set up as part of the initializer. For properties the same thing can be achieved with either:

  • TyphoonPropertyInjectionDelegate - provides beforePropertyInjection and afterPropertyInjection methods
  • Manually specifying the callback method names.

Bearing in mind this feature of the Objective-C runtime, if there's anything else that could've been done to make your experience better (ie more self-documenting) I would be appreciate hearing your thoughts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants