Coder Social home page Coder Social logo

appsquickly / typhoon Goto Github PK

View Code? Open in Web Editor NEW
2.7K 2.7K 269.0 129.53 MB

Powerful dependency injection for Objective-C ✨✨ (https://PILGRIM.PH is the pure Swift successor to Typhoon!!)✨✨

Home Page: https://pilgrim.ph

License: Apache License 2.0

HTML 0.93% XSLT 2.83% CSS 2.23% Shell 0.47% Ruby 0.19% Objective-C 92.64% C 0.05% Swift 0.64% Rich Text Format 0.04%
dependency-injection di inversion-of-control ioc ioc-container typhoon

typhoon's People

Contributors

akiraspeirs avatar alexgarbarev avatar cognitivedisson avatar dani-gavrilov avatar drodriguez avatar emailrus avatar eriksundin avatar etolstoy avatar ivanushakov avatar jasperblues avatar jeffbnimble avatar jervine10 avatar jgongo avatar kemalbakacak avatar manolosavi avatar mbaltaks avatar mogol avatar nickynick avatar peterkutasi avatar plandem avatar readmecritic avatar rhgills avatar ricowere avatar romainlofaso avatar sergkovb avatar simonkang avatar skywinder avatar warnyul avatar xiangtiandai avatar xr1337 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typhoon's Issues

Logging seems excessive

Consider the output of a single test case, all of which is from the framework and none from the actual test.

Test Case '-[TyphoonXmlComponentFactoryTests test_returns_component_from_factory_component]' started.
2013-07-23 10:18:11.653 otest[38865:303] Resource: MiddleAgesAssembly.xml
2013-07-23 10:18:11.654 otest[38865:303] Registering: Knight with key: knight
2013-07-23 10:18:11.654 otest[38865:303] $$$$$$$$$$$$$$ Here's the injected property: <TyphoonPropertyInjectedAsCollection: self.  name=favoriteDamsels, _values=(
    "<TyphoonTypeConvertedCollectionValue: self.textValue=mary, self.requiredType=NSString>",
    "<TyphoonTypeConvertedCollectionValue: self.textValue=jane, self.requiredType=NSString>"
)>
2013-07-23 10:18:11.655 otest[38865:303] $$$$$$$$$$$$$$ Here's the injected property: <TyphoonPropertyInjectedAsCollection: self.name=friends,   _values=(
    "<TyphoonByReferenceCollectionValue: 0x108117870>",
    "<TyphoonByReferenceCollectionValue: 0x108102430>"
)>
2013-07-23 10:18:11.655 otest[38865:303] Registering: Knight with key: knightWithCollections
2013-07-23 10:18:11.655 otest[38865:303] Registering: CampaignQuest with key: quest
2013-07-23 10:18:11.656 otest[38865:303] Registering: CampaignQuest with key: anotherQuest
2013-07-23 10:18:11.656 otest[38865:303] Registering: CavalryMan with key: anotherKnight
2013-07-23 10:18:11.656 otest[38865:303] Registering: CavalryMan with key: yetAnotherKnight
2013-07-23 10:18:11.657 otest[38865:303] Registering: NSURL with key: serviceUrl
2013-07-23 10:18:11.657 otest[38865:303] Registering: SwordFactory with key: swordFactory
2013-07-23 10:18:11.657 otest[38865:303] Registering: Sword with key: blueSword
2013-07-23 10:18:11.658 otest[38865:303] Resource: SomeProperties.properties
2013-07-23 10:18:11.658 otest[38865:303] Attaching mutator: <TyphoonPropertyPlaceholderConfigurer: 0x100152e80>
2013-07-23 10:18:11.658 otest[38865:303] Resource: ExceptionTestAssembly.xml
2013-07-23 10:18:11.659 otest[38865:303] Registering: NSURL with key: anotherServiceUrl
2013-07-23 10:18:11.659 otest[38865:303] Registering: NSString with key: aBlaString
2013-07-23 10:18:11.660 otest[38865:303] Resource: CircularDependenciesAssembly.xml
2013-07-23 10:18:11.660 otest[38865:303] Registering: ClassADependsOnB with key: classA
2013-07-23 10:18:11.660 otest[38865:303] Registering: ClassBDependsOnA with key: classB
2013-07-23 10:18:11.661 otest[38865:303] Registering: ClassCDependsOnDAndE with key: classC
2013-07-23 10:18:11.661 otest[38865:303] Registering: ClassDDependsOnC with key: classD
2013-07-23 10:18:11.661 otest[38865:303] Registering: ClassEDependsOnC with key: classE
2013-07-23 10:18:11.662 otest[38865:303] ###### My dependencies have not yet been injected. Here's what I look like: <CampaignQuest: self.  imageUrl=(null)>
2013-07-23 10:18:11.662 otest[38865:303] Property setter invocation: <NSInvocation: 0x101d08ca0>
2013-07-23 10:18:11.663 otest[38865:303] $$$$$$$$$$$$$$$$$ My dependencies have been injected. And I know look like this: <CampaignQuest: self.  imageUrl=http://www.  appsquick.ly/theQuest.jpg>
2013-07-23 10:18:11.663 otest[38865:303] Parsing typeCode: f
2013-07-23 10:18:11.663 otest[38865:303] #################### CavalryMan before properties set
2013-07-23 10:18:11.663 otest[38865:303] Parsing typeCode: c
2013-07-23 10:18:11.664 otest[38865:303] Property setter invocation: <NSInvocation: 0x104d00a40>
2013-07-23 10:18:11.664 otest[38865:303] ############# CavalryMan after properties set
Test Case '-[TyphoonXmlComponentFactoryTests test_returns_component_from_factory_component]' passed (0.011 seconds).  

Perhaps a logging framework should be introduced? I'm most familiar with CocoaLumberjack myself, which has static, per file log levels.

Incorrect podscpec?

After cloning and installing Typhoon from my own repo using CocoaPods I was getting errors when trying to install the dependencies (undefined method `pod' for Pod:Module). I have noticed that the first line of the podspec reads:

pod do |spec|

while in the CocoaPods documentation you can find the first line as

Pod::Spec.new do |spec|

After changing that line in my own repo it seems I no longer have install issues with CocoaPods.

Lifecycle/scope

Is called lifecycle in code assembly and scope in XML assembly. They should match.

TyphoonBlockComponentFactory dispatch non component methods

TyphoonBlockComponentFactory has a resolveInstanceMethod that allow using the Assembly interface to retrieve components. . . this is more prefereable than resolving by string.

Perhaps it could be enhanced to trampoline non component matching methods back to the assembly class?

This would allow custom factory methods. For example:

[assembly photoClientForId:facebook caching:YES];

Exceptions not reported properly on Xcode5

Example: Telling Typhoon to inject a property that doesn't exist eats the exception

  • (id)yourDetailsController
    {
    return [TyphoonDefinition withClass:[MPYourDetailsController class] properties:^(TyphoonDefinition* definition)
    {
    //property 'yourDetailsView' does not exist
    [definition injectProperty:@selector(yourDetailsView) withDefinition:[self yourDetailsView]];
    }];
    }

No meaningful error is thrown. . .

Property Configurer

Should ignore lines that begin with a hash ('#') character.

(This currently works - as in doesn't break anything - but wastes memory).

Circular dependencies are broken

I don’t know if the circular dependencies code is WIP or not, but this is one problem we have found trying to use circular dependencies.

The problem can be seen in both tests about circular dependencies. I’m going to choose the first one (by_reference) but the other one shows the same behaviour.

If you change the test to read like the following code the asserts marked as “Fails” will fail:

- (void)test_resolves_circular_dependencies_for_property_injected_by_reference
{
    ClassADependsOnB* classA = [_circularDependenciesFactory componentForKey:@"classA"];
    NSLog(@"Dependency on B: %@", classA.dependencyOnB);
    assertThat(classA.dependencyOnB, notNilValue());

    // Fails
    assertThat(classA, equalTo(classA.dependencyOnB.dependencyOnA));

    id dependencyABA = classA.dependencyOnB.dependencyOnA;
    // Fails
    assertThat([[dependencyABA dependencyOnB] class], equalTo([ClassBDependsOnA class]));



    ClassBDependsOnA* classB = [_circularDependenciesFactory componentForKey:@"classB"];
    NSLog(@"Dependency on A: %@", classB.dependencyOnA);
    assertThat(classB.dependencyOnA, notNilValue());

    // Fails
    assertThat(classB, equalTo(classB.dependencyOnA.dependencyOnB));

    id dependencyBAB = classB.dependencyOnA.dependencyOnB;
    // Fails
    assertThat([[dependencyBAB dependencyOnA] class], equalTo([ClassADependsOnB class]));
}

The first assert is something that we supposed it will happen when we specified the circular dependency (if A depends on B and B depends on A, the link will be made between two instances, not more). We don’t know if it is what Typhoon is trying to solve.

The second assert is more dangerous, since a chain of modules might be providing the dependencies, and someone might end with an instance of an unexpected type. I know that it has to go through 3 jumps, but I think that creating a bad typed object graph should be avoided.

This is what I see in my debugger when I stop the test just before the first assert is run:

debugger just before first assert

As you can see, the first and the second objects are created with the right types. The third object is also the right type, but instead of being the same object as the first, it is another completely different object. Finally the dependency of that object on ClassB is pointing to itself (!?) which is, obviously, of the wrong class.

From my analysis of what happens this is the sequence of steps that leads to this:

  1. TyphoonSharedComponentFactoryTests.m#157 starts the process asking for a “classA”.
  2. Through several calls we end in -[TyphoonComponentFactory(InstanceBuilder) doPropertyInjection:property:typeDescriptor:].
  3. The first call to -[TyphoonComponentFactory(InstanceBuilder) evaluateCircularDependency:property:instance:] is made. Since _currentlyResolvingReferences is empty, the method simply updates the dictionary with @"classB": <ClassADependsOnB: 0x1060052f0> (this is strange, but seems that this dictionary tells that ClassADependsOnB is resolving "classB" reference?).
  4. Going back to doPropertyInjection:property:typeDescriptor:, the code checks that this is not (yet) a circular dependent property, and proceeds with the injection.
  5. Since this property is a reference to "classB", through several calls we end, again, at doPropertyInjection:property:typeDescriptor, but this time we are creating a ClassBDependsOnA and we are processing the dependencyOnA property.
  6. The second call to evaluateCircularDependency:property:instance: is made. At this point _currentlyResolvingReferences only has one element (the one created in step 3), so things work more or less like before, and a new pair @"classA": <ClassBDependsOnA: 0x102446650> is added to the dictionary. I think here lies one of our problems, since we are already resolving "classA" from the start, but we never added it to the _currentlyResolvingReferences dictionary. This makes the component factory start creating another ClassADependsOnB, which is not what we expect.
  7. Going back to doPropertyInjection:property:typeDescriptor:, things proceed as in step 4, and we start creating another "classA" reference.
  8. Again, through several calls we end once more in doPropertyInjection:property:typeDescriptor:, trying to create a ClassADependsOnB. This time the things are different, because the circular dependency code starts being exercised.
  9. The third call to evaluateCircularDependency:property:instance: is made. This time we have a "classA" in the dictionary, so this instance circularDependentProperties dictionary is updated with the pair @"dependencyOnB": @"classB". Then we overwrite the _currentlyResolvingReferences dictionary: the pair we created in step 3 now points to this second instance of ClassADependsOnB (for reference <ClassADependsOnB: 0x102446a40>).
  10. This is the first time that after going back to doPropertyInjection:property:typeDescriptor: the injection doesn’t get made, and the first time we are able to “escape” doPropertyInjection:property:typeDescriptor:.
  11. We end up in -[TyphoonComponentFactory(InstanceBuilder) injectCircularDependenciesOn:] for the first time. This instance has a circular dependency detected, "dependencyOnB", which references "classB". However, under that name in _currentlyResolvingReferences we have an instance of ClassADependsOnB (the one stored in step 9, and before that another one of the same class in step 3). So we end injecting a ClassADependsOnB into a dependencyOnB property. The worse thing, we stored <ClassADependsOnB: 0x102446a40> in step 9, and we are recovering it, and injecting it in itself.
  12. Going back in the stack, in -[TyphoonComponentFactory componentForKey:] we proceed to remove all objects of _currentlyResolvingReferences. It doesn’t matter that much at this point, since the first two instances didn’t detect any circular references.

There are other smaller bugs related to this code that might generate confusion:

  • When the injection is “delayed” because it is a circular dependency in doPropertyInjection:property:typeDescriptor:, the invocation is made anyway, which I think produces a call to the setter with a nil argument. Some classes might not like that. The invocation should be avoided if possible, or this side-effect should be documented.
  • -[TyphoonComponentFactory(InstanceBuilder) doAfterPropertyInjectionOn:withDefinition:] is invoked before circular dependencies are setup, so the classes that expects those properties to be set will obtain unexpected results. The invocation of that method should be done after the circular dependencies had been injected, or the behaviour documented.

Allow block based assembly overrides

Let's say you have a block based assembly like this:


@interface MiddleAgesAssembly : TyphoonAssembly
- (id)knight;
- (id)cavalryMan;
- (id)defaultQuest;
- (id)anotherKnight;
- (id)yetAnotherKnight;
@end

And you want to have a new assembly with the same definitions except for one. I would like to be able to do something like this:

@interface MiddleAgesAssemblyOverride : MiddleAgesAssembly
@end

@implementation MiddleAgesAssemblyOverride
- (id)knight
{
    // Override definition of knight while maintaining the rest of definitions unchanged
}
@end

Typhoon currently does not allow you to do this

Problem with circular dependencies and singletons

When you create chains of circular dependent singletons and mix them with some non singletons components using initializer injection, sometimes you instantiate a singleton several times before registering in the _singletons dictionary. This ends up with different components pointing to different instances of the same singleton.

I can provide a failing test for this sepecific bug.

I also added a couple of sanity checks in TyphoonComponentFactory to avoid registering the same singleton twice. The soution is not specially elegant, but it seems to fix the problem.

Code organization: separation of private/public methods or step-down rule?

The existing organization of source files seems to consists of heavy use of pragma marks as separators, dividing methods into categories such as: initialization/dealloc and private methods.

I'm used to following the step-down rule, wherein methods are arranged such that a method definition is found below, and as close to as possible, the first method that calls it. I might annotate individual methods with comments, if helpful. For example, if overriding -(BOOL)isEqual:, I might make a note that that method is originally defined in NSObject.

The main advantages I see when following the step down rule are less jumping around the methods in an individual class and increased understanding.

Naturally, both these approaches conflict. I've rearranged the code to follow the step down rule myself when trying to understand what a particular class does and have usually left it that way after any subsequent refactorings. I feel that we should decide on one of these approaches going forward and stick to it, for consistency.

I'm also going to try and do a better job going forward matching the style of the code as I'm writing it, so you don't have to go back and fix my out-of-place formatting. I don't think Xcode has anything like this, but does AppCode support project level code style settings? For indentation and code generation and the like? I know AppCode has extensive style settings, but I seem to recall that they are global.

Should Tests/Pods be checked into version control?

The main argument I'm aware of for doing so is to ensure that all checkouts of the repo are able to successfully build, regardless of if any depended upon cocoapods have had their git repositories deleted or are otherwise unavailable. This obviously does not apply to the Typhoon pod, which is in the same repository as the Tests client; but it does apply to the other test dependencies, OCHamcrest and OCMockito.

In addition, by checking Tests/Pods into VCS, assuming we remember to run pod update or have a script to run pod update for us before each commit, we avoid the need for a pod install before being able to run unit tests with a fresh clone of the repo. We also avoid the need for a pod update when pulling changes from the repository.

On the other hand, we currently end up with redundant and duplicate changes. If we change a library source file, then run pod update, then commit, we will see two changes to the same source file; one change will be made to the 'actual' source file under Source, and the other made to the Tests/Pods copy. IIRC specifying a local path for a pod should usually result in an alias to the original file under Pods/, not a copy; I'll have to look into this as well.

EDIT: Okay, after deleting the Pods/ directory and running pod install, copies of Typhoon library files are no longer made under Pods/ - the original files under Source/ are used instead, as desired. This may or may not be related to having just updated coocapods. Manually deleting the Pods/ directory, and running pod install after some configuration changes appears necessary.

So, to summarize:

Check Pods/ into VCS?

For:

  • risk of OCHamcrest and OCMockito repositories disappearing or being temporarily unavailable when we clone a fresh copy of the Typhoon repository and wish to run unit tests
  • don't have to know to run pod install under Tests/ when cloning the fresh
  • don't have to remember to run pod update under Tests/ after git pull

Against:

  • have to remember to run pod update before committing (can be mitigated by automatically running as part of builds, see #53)
  • cocoapods clutter in changesets/commit messages (EDIT: No longer an issue as duplicates of source files are not made)

Currently I'm for, especially if I can figure out why copies are being made in Pods/ instead of aliasing to the original source files.

Move Typhoon to its own org in GitHub

I started Typhoon on my own, but we have some fantastic contributors now. . .

. . to recognize shared ownership, when it reaches 400 stars in GitHub, we'll move it to its own organization page.

Let Typhoon use manually created objects while using blocks

I've done the exercise of building a Core Data Stack using Typhoon and block style definitions. I found it extremely verbose, and I think the main reason is that Typhoon doesn't let you inject or use manually created objects. I understand this is due to the fact that you can't manually create objects in XML, but I don't see any reason why this also should be the case while using blocks.

Here you have the complete code: https://gist.github.com/jgongo/5075937

As you can see, there are four Typhoon definitions just to emulate the following snippet:

NSURL *applicationDocumentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *storeURL = [applicationDocumentsDirectory URLByAppendingPathComponent:@"database.sqlite"];

Also notice the use of hard coded constants in applicationDocumentsDirectories

I think this could be simplified a lot if:

  1. Typhoon would let you manually create objects, not only definitions
  2. Typhoon would let you use manually created objects as factories
  3. Typhoon would let you inject manually created objects, in addition to text values and references

Create an id<TyphoonComponentFactoryMutator> that can insert mocks for some definitions

An id can be attached to the factory to mutate definitions.

So far we have the TyphoonPropertyPlaceholderConfigurer. .

I'm thinking it might be nice to attach a mutator that will tell the assembly to override a given component definition, replacing it with a mock or stub.

This would be useful when you want to do integration testing (test a class along with its collaborators), but configuring a certain part of the assembly to behave in accordance with the test scenario.

ant build broken with Xcode 4

ant build-publish-dry-run

...

__build.library.ios.simulator:
     [exec] 2013-08-31 13:35:01.213 xcodebuild[48077:1207] XcodeColors: load (v10.1)
     [exec] 2013-08-31 13:35:01.214 xcodebuild[48077:1207] XcodeColors: pluginDidLoad:
     [exec] xcodebuild: error: SDK "iphonesimulator7.0" cannot be located.

BUILD FAILED
/Users/rhgill/Code/Typhoon/build.xml:89: exec returned: 64

Circular Dependencies causes crash

Steps to reproduce:

  1. Create a login view controller:
  • (id)loginController
    {
    return [TyphoonDefinition withClass:[MPLoginController class] initialization:^(TyphoonInitializer* initializer)
    {
    initializer.selector = @selector(initWithLoginView:);
    [initializer injectWithDefinition:[self loginView]];
    } properties:^(TyphoonDefinition* definition)
    {
    [definition injectProperty:@selector(authorizationUrl) withValueAsText:@"${oauth.authorization.url}"];
    [definition injectProperty:@selector(authentication) withDefinition:[self oauthAuthentication]];
    [definition injectProperty:@selector(keychainItemName) withValueAsText:@"${oauth.keychain.item.name}"];
    [definition injectProperty:@selector(loginView) withDefinition:[self loginView]];
    }];
    }
  • (id)loginView
    {
    return [TyphoonDefinition withClass:[MPLoginView class] properties:^(TyphoonDefinition* definition)
    {
    [definition injectProperty:@selector(delegate) withDefinition:[self loginController]];
    }];
    }
  1. Inject the loginViewController into a root view controller:
  • (MPRootViewController_)rootViewController;
    {
    return (MPRootViewController_) [TyphoonDefinition withClass:[MPRootViewController class]
    initialization:^(TyphoonInitializer* initializer)
    {
    initializer.selector = @selector(initWithMainContentViewController:);
    [initializer injectWithDefinition:[self loginController]];
    } properties:^(TyphoonDefinition* definition)
    {
    definition.afterPropertyInjection = @selector(mplusInitialization);
    }];
    }

EXPECTED OUTCOME:

  1. Works

ACTUAL OUTCOME

Causes crash.

Allow easier definition of additional type converters (ie. in the Assembly).

Typhoon allows the definition of additional type converters like this:

TyphoonComponentFactory* factory = [TyphoonBlockComponentFactory factoryWithAssembly:[ApplicationAssembly assembly]];
[[TyphoonTypeConverterRegistry shared] register:[[HistoryModeTypeConverter alloc] init] forClassOrProtocol:[HistoryMode class]];

It might be nice to allow defining type converters in the assembly itself.

Autofac-style parameter injection.

I just started looking at IoC containers for iPhone today and have been testing Typhoon for a bit now.

I noticed it only accepts parameterless methods in the TyphoonAssembly subclass. What is the recommended way of working with things that take blocks? For instance a HTTP request that take blocks for success/failure.

Is the only option to let Typhoon instantiate them and set them afterwards, when returned from the container? Or do i have to create a factory?

Multiple xml configuration files?

Hi There,

Great work so far! I was wondering if the framework supports loading multiple xml config files? The reason I ask is that on a large project, a single config can often become unwieldy, and it often helps to be able to break it down into by functional area or some other organizing principle.

Is this supported, and if not, is it planned?

-Bruce

By default, greedily choose the longest satisfiable constructor

Ala PicoContainer (see third from the top, How does PicoContainer decide what constructor to use?), this should reduce the number of instances in which you must manually set the selector on the initializer. It's particularly painful to do so, at least in Xcode, as the selectors suggested for autocomplete are not necessarily on the class you're actually trying to initialize.

Error when initWith returns a new pointer

Hi Jasper,

After the modification in 1.1.3 I was getting another error: the NSManagedObjectModel wan't correctly initialized. So I think the problem is:
-[NSManagedObjectModel initWithContentsOfURL:] seems to be discarding the current instance, and creating and returning a new instance.
In 1.1.3 Typhoon ignores the returned value, so it returns the original instance, uninitialized
In 1.1.2 Typhoon was correctly copying and returning the returned value, but was somehow keeping a reference and releasing the old instance. That was causing an over releasing of that old instance.
Now that I have written it down I feel there's something that doesn't add up... any way, have you taken into account those cases, where initXXX discards the current instance and creates a new one?

Allow easier definition of property configurers (ie in the Assembly)

Typhoon supports property configurers. The current way to define them is:

TyphoonComponentFactory* factory = [TyphoonBlockComponentFactory factoryWithAssembly:[ApplicationAssembly assembly]];

id <TyphoonResource> configurationProperties = [TyphoonBundleResource withName:@"Configuration.properties"];
[factory attachMutator:[TyphoonPropertyPlaceholderConfigurer configurerWithResource:configurationProperties]];

It might be nice to allow definition of configurers in the Assembly (code or xml).

Method-injection

Since 1.1.0 method injection - injecting via a method without corresponding property raises an error.

Coverage reports are broken again

I've found coverage reports work better with real source files (as opposed to library).

We could link in using Xcode's sub-project feature.

New scope: WeakSingleton

This scope will:

  • Create a new instance if available
  • Allocate it to a pool
  • When no classes are using it, drain it from the pool.

Add support for factories

I was trying to create a Core Data stack using Typhoon and faced the following problem: I had to create the managed object model injecting the URL of the model in the initializer. The URL of the model is typically constructed this way:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataTest" withExtension:@"momd"];

As far as I know (correct me if I'm wrong) there is no way to create / inject such an object using Typhoon. I could build the main bundle object using Typhoon, but then I have no way of invoking a method on that object to get another object that gets injected in an additional object.

I think the general problem to be solved is to add support for factories: in fact the main bundle is a URL factory, using the method shown above. So maybe we could add something like this to Typhoon:

return [TyphoonDefinition withFactory:[self mainBundle] creator:^(TyphoonCreator *creator) {
    creator.selector = @selector(URLForResource:withExtension:);
    [creator injectParameterAt:0 withValueAsText:@"CoreDataTest" requiredTypeOrNil:[NSString class]];
    [creator injectParameterAt:1 withValueAsText:@"momd" requiredTypeOrNil:[NSString class]];
}];

I've noticed I can have a workaround for this problem using type converters, creating a converter that converts the string "CoreDataTest.momd" to the required NSURL, but this would prevent the creation of a "natural" type converter from strings to NSURLs, as Typhoon only supports a converter for a given type.

What do you think? Am I missing anything?

Question about lazy instantiation, another about child (lazy) contexts

I'm just asking here since I hadn't seen another forum, but please let me know if I'm not in the right place:

  1. Does Typhoon have a provision for lazy instantiation of objects? Is the "prototype" scope for this purpose? Could you explain a little more about this?
  2. Is there any way to initialize "child" contexts, which would be aware of the main one? If so, is it possible to do deferred initialization of child contexts?

Thanks,
Bruce

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.