Skip to content

Commit

Permalink
Merge pull request #444 from appsquickly/preattaching-infrastructure
Browse files Browse the repository at this point in the history
Preattaching infrastructure components
  • Loading branch information
jasperblues committed Nov 8, 2015
2 parents 080afaf + a84c7b2 commit 4da05e0
Show file tree
Hide file tree
Showing 15 changed files with 209 additions and 39 deletions.
2 changes: 1 addition & 1 deletion Source/Configuration/Startup/TyphoonStartup.m
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ + (void)swizzleSetDelegateMethodOnApplicationClass
if (initialFactory) {
id<TyphoonDefinitionPostProcessor> processor = [self configPostProcessor];
if (processor) {
[initialFactory attachPostProcessor:processor];
[initialFactory attachDefinitionPostProcessor:processor];
}
[self injectInitialFactoryIntoDelegate:delegate];
[TyphoonComponentFactory setFactoryForResolvingUI:initialFactory];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

- (NSArray *)definitions;

- (NSArray *)preattachedInfrastructureComponents;

- (TyphoonDefinition *)definitionForKey:(NSString *)key;

- (Class)assemblyClassForKey:(NSString *)key;
Expand Down
31 changes: 28 additions & 3 deletions Source/Factory/Assembly/TyphoonAssembly.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
@interface TyphoonAssembly () <TyphoonObjectWithCustomInjection>

@property(readwrite) NSSet *definitionSelectors;
@property(readwrite) NSArray *preattachedInfrastructureComponents;

@property(readwrite) NSDictionary *assemblyClassPerDefinitionKey;

Expand Down Expand Up @@ -123,6 +124,7 @@ - (id)init {
_definitionBuilder = [[TyphoonAssemblyDefinitionBuilder alloc] initWithAssembly:self];
_adviser = [[TyphoonAssemblyAdviser alloc] initWithAssembly:self];
_collector = [[TyphoonCollaboratingAssembliesCollector alloc] initWithAssemblyClass:[self class]];
_preattachedInfrastructureComponents = [NSArray array];

[self proxyCollaboratingAssembliesPriorToActivation];
}
Expand Down Expand Up @@ -197,12 +199,32 @@ - (void)makeDefault {
[_factory makeDefault];
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (void)attachPostProcessor:(id <TyphoonDefinitionPostProcessor>)postProcessor {
[self attachDefinitionPostProcessor:postProcessor];
}
#pragma clang diagnostic pop

- (void)attachDefinitionPostProcessor:(id <TyphoonDefinitionPostProcessor>)postProcessor {
if (!_factory) {
[NSException raise:NSInternalInconsistencyException
format:@"attachPostProcessor: requires the assembly to be activated."];
[self preattachInfrastructureComponent:postProcessor];
}
[_factory attachDefinitionPostProcessor:postProcessor];
}

- (void)attachInstancePostProcessor:(id<TyphoonInstancePostProcessor>)postProcessor {
if (!_factory) {
[self preattachInfrastructureComponent:postProcessor];
}
[_factory attachInstancePostProcessor:postProcessor];
}

- (void)attachTypeConverter:(id<TyphoonTypeConverter>)typeConverter {
if (!_factory) {
[self preattachInfrastructureComponent:typeConverter];
}
[_factory attachPostProcessor:postProcessor];
[_factory attachTypeConverter:typeConverter];
}

- (id)objectForKeyedSubscript:(id)key {
Expand Down Expand Up @@ -333,5 +355,8 @@ - (Class)assemblyClassForKey:(NSString *)key
}
}

- (void)preattachInfrastructureComponent:(id)component {
_preattachedInfrastructureComponents = [_preattachedInfrastructureComponents arrayByAddingObject:component];
}

@end
10 changes: 9 additions & 1 deletion Source/Factory/Internal/TyphoonBlockComponentFactory.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
#import "TyphoonAssembly+TyphoonAssemblyFriend.h"
#import "TyphoonAssemblyPropertyInjectionPostProcessor.h"
#import "TyphoonIntrospectionUtils.h"
#import "TyphoonTypeConverterRegistry.h"
#import "TyphoonTypeConverter.h"
#import "TyphoonInstancePostProcessor.h"
#import "TyphoonComponentFactory+TyphoonDefinitionRegisterer.h"
#import "TyphoonPreattachedComponentsRegisterer.h"

@interface TyphoonComponentFactory (Private)

Expand Down Expand Up @@ -57,8 +62,11 @@ - (id)initWithAssemblies:(NSArray *)assemblies
{
self = [super init];
if (self) {
[self attachPostProcessor:[TyphoonAssemblyPropertyInjectionPostProcessor new]];
[self attachDefinitionPostProcessor:[TyphoonAssemblyPropertyInjectionPostProcessor new]];
TyphoonPreattachedComponentsRegisterer *preattachedComponentsRegisterer = [[TyphoonPreattachedComponentsRegisterer alloc] initWithComponentFactory:self];

for (TyphoonAssembly *assembly in assemblies) {
[preattachedComponentsRegisterer doRegistrationForAssembly:assembly];
[self buildAssembly:assembly];
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@

- (void)addDefinitionToRegistry:(TyphoonDefinition *)definition;

- (void)addInstancePostProcessor:(id <TyphoonInstancePostProcessor>)postProcessor;
- (void)addInstancePostProcessor:(id <TyphoonInstancePostProcessor>)postProcessor DEPRECATED_MSG_ATTRIBUTE("use attachInstancePostProcessor instead");

@end
22 changes: 19 additions & 3 deletions Source/Factory/TyphoonComponentFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#import <Foundation/Foundation.h>
#import "TyphoonDefinitionPostProcessor.h"
#import "TyphoonInstancePostProcessor.h"
#import "TyphoonTypeConverter.h"
#import "TyphoonComponentsPool.h"

@class TyphoonDefinition;
Expand Down Expand Up @@ -80,10 +82,24 @@
- (void)makeDefault;

/**
Attach a TyphoonComponentFactoryPostProcessor to this component factory.
@param postProcessor The post-processor to attach.
Attach a TyphoonDefinitionPostProcessor to this component factory.
@param postProcessor The definition post processor to attach.
*/
- (void)attachPostProcessor:(id <TyphoonDefinitionPostProcessor>)postProcessor;
- (void)attachDefinitionPostProcessor:(id<TyphoonDefinitionPostProcessor>)postProcessor;

/**
Attach a TyphoonInstancePostProcessor to this component factory.
@param postProcessor The instance post processor to attach.
*/
- (void)attachInstancePostProcessor:(id<TyphoonInstancePostProcessor>)postProcessor;

/**
Attach a TyphoonTypeConverter to this component factory.
@param typeConverter The type converter to attach.
*/
- (void)attachTypeConverter:(id<TyphoonTypeConverter>)typeConverter;

- (void)attachPostProcessor:(id<TyphoonDefinitionPostProcessor>)postProcessor DEPRECATED_MSG_ATTRIBUTE("use attachDefinitionPostProcessor instead");

@end

Expand Down
35 changes: 26 additions & 9 deletions Source/Factory/TyphoonComponentFactory.m
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ - (id)init
_typeConverterRegistry = [[TyphoonTypeConverterRegistry alloc] init];
_definitionPostProcessors = [[NSMutableArray alloc] init];
_instancePostProcessors = [[NSMutableArray alloc] init];
[self attachPostProcessor:[TyphoonParentReferenceHydratingPostProcessor new]];
[self attachDefinitionPostProcessor:[TyphoonParentReferenceHydratingPostProcessor new]];
[self attachAutoInjectionPostProcessorIfNeeded];
[self attachPostProcessor:[TyphoonFactoryPropertyInjectionPostProcessor new]];
[self attachDefinitionPostProcessor:[TyphoonFactoryPropertyInjectionPostProcessor new]];
}
return self;
}
Expand All @@ -92,7 +92,7 @@ - (void)attachAutoInjectionPostProcessorIfNeeded

NSNumber *value = bundleInfoDictionary[@"TyphoonAutoInjectionEnabled"];
if (!value || [value boolValue]) {
[self attachPostProcessor:[TyphoonFactoryAutoInjectionPostProcessor new]];
[self attachDefinitionPostProcessor:[TyphoonFactoryAutoInjectionPostProcessor new]];
}
}

Expand Down Expand Up @@ -242,17 +242,32 @@ - (void)enumerateDefinitions:(void (^)(TyphoonDefinition *definition, NSUInteger
}
}


- (void)attachPostProcessor:(id<TyphoonDefinitionPostProcessor>)postProcessor
{
LogTrace(@"Attaching post processor: %@", postProcessor);
- (void)attachDefinitionPostProcessor:(id<TyphoonDefinitionPostProcessor>)postProcessor {
LogTrace(@"Attaching definition post processor: %@", postProcessor);
[_definitionPostProcessors addObject:postProcessor];
if ([self isLoaded]) {
LogDebug(@"Definitions registered, refreshing all singletons.");
[self unload];
}
}

- (void)attachInstancePostProcessor:(id<TyphoonInstancePostProcessor>)postProcessor {
LogTrace(@"Attaching instance post processor: %@", postProcessor);
[_instancePostProcessors addObject:postProcessor];
}

- (void)attachTypeConverter:(id<TyphoonTypeConverter>)typeConverter {
LogTrace(@"Attaching type conveter: %@", typeConverter);
[_typeConverterRegistry registerTypeConverter:typeConverter];
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (void)attachPostProcessor:(id<TyphoonDefinitionPostProcessor>)postProcessor
{
[self attachDefinitionPostProcessor:postProcessor];
}
#pragma clang diagnostic pop

- (void)inject:(id)instance
{
Expand Down Expand Up @@ -458,10 +473,12 @@ - (void)addDefinitionToRegistry:(TyphoonDefinition *)definition
[_registry addObject:definition];
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (void)addInstancePostProcessor:(id<TyphoonInstancePostProcessor>)postProcessor
{
[_instancePostProcessors addObject:postProcessor];
[self attachInstancePostProcessor:postProcessor];
}

#pragma clang diagnostic pop

@end
6 changes: 3 additions & 3 deletions Source/Factory/TyphoonDefinitionRegisterer.m
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,13 @@ - (void)registerInfrastructureComponentFromDefinition

id infrastructureComponent = [_componentFactory newOrScopeCachedInstanceForDefinition:_definition args:nil];
if ([_definition.type conformsToProtocol:@protocol(TyphoonDefinitionPostProcessor)]) {
[_componentFactory attachPostProcessor:infrastructureComponent];
[_componentFactory attachDefinitionPostProcessor:infrastructureComponent];
}
else if ([_definition.type conformsToProtocol:@protocol(TyphoonInstancePostProcessor)]) {
[_componentFactory addInstancePostProcessor:infrastructureComponent];
[_componentFactory attachInstancePostProcessor:infrastructureComponent];
}
else if ([_definition.type conformsToProtocol:@protocol(TyphoonTypeConverter)]) {
[_componentFactory.typeConverterRegistry registerTypeConverter:infrastructureComponent];
[_componentFactory attachTypeConverter:infrastructureComponent];
}
}

Expand Down
23 changes: 23 additions & 0 deletions Source/Factory/TyphoonPreattachedComponentsRegisterer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
////////////////////////////////////////////////////////////////////////////////
//
// TYPHOON FRAMEWORK
// Copyright 2015, Typhoon Framework Contributors
// All Rights Reserved.
//
// NOTICE: The authors permit you to use, modify, and distribute this file
// in accordance with the terms of the license agreement accompanying it.
//
////////////////////////////////////////////////////////////////////////////////

#import <Foundation/Foundation.h>

@class TyphoonComponentFactory;
@class TyphoonAssembly;

@interface TyphoonPreattachedComponentsRegisterer : NSObject

- (instancetype)initWithComponentFactory:(TyphoonComponentFactory *)componentFactory;

- (void)doRegistrationForAssembly:(TyphoonAssembly *)assembly;

@end
48 changes: 48 additions & 0 deletions Source/Factory/TyphoonPreattachedComponentsRegisterer.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
////////////////////////////////////////////////////////////////////////////////
//
// TYPHOON FRAMEWORK
// Copyright 2015, Typhoon Framework Contributors
// All Rights Reserved.
//
// NOTICE: The authors permit you to use, modify, and distribute this file
// in accordance with the terms of the license agreement accompanying it.
//
////////////////////////////////////////////////////////////////////////////////

#import "TyphoonPreattachedComponentsRegisterer.h"
#import "TyphoonComponentFactory.h"
#import "TyphoonAssembly+TyphoonAssemblyFriend.h"

@interface TyphoonPreattachedComponentsRegisterer ()

@property (strong, nonatomic) TyphoonComponentFactory *factory;

@end

@implementation TyphoonPreattachedComponentsRegisterer

- (instancetype)initWithComponentFactory:(TyphoonComponentFactory *)componentFactory {
self = [super init];
if (self) {
_factory = componentFactory;
}
return self;
}

- (void)doRegistrationForAssembly:(TyphoonAssembly *)assembly {
NSArray *infrastructureComponents = [assembly preattachedInfrastructureComponents];

for (id component in infrastructureComponents) {
if ([component conformsToProtocol:@protocol(TyphoonDefinitionPostProcessor)]) {
[self.factory attachDefinitionPostProcessor:component];
}
else if ([component conformsToProtocol:@protocol(TyphoonInstancePostProcessor)]) {
[self.factory attachInstancePostProcessor:component];
}
else if ([component conformsToProtocol:@protocol(TyphoonTypeConverter)]) {
[self.factory attachTypeConverter:component];
}
}
}

@end
43 changes: 31 additions & 12 deletions Tests/Factory/Assembly/TyphoonAssemblyTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#import "TyphoonLoopedCollaboratingAssemblies.h"
#import "MediocreQuest.h"
#import "OCLogTemplate.h"
#import "TyphoonPatcher.h"
#import "TyphoonInstancePostProcessorMock.h"
#import "NSNullTypeConverter.h"

@interface TyphoonAssemblyTests : XCTestCase
@end
Expand Down Expand Up @@ -146,18 +149,6 @@ - (void)test_before_activation_raises_exception_when_invoking_TyphoonComponentFa
}
}

- (void)test_before_activation_raises_exception_when_invoking_attachPostProcessor
{
@try {
MiddleAgesAssembly *assembly = [MiddleAgesAssembly assembly];
[assembly attachPostProcessor:nil];
XCTFail(@"Should have thrown exception");
}
@catch (NSException *e) {
XCTAssertEqualObjects(@"attachPostProcessor: requires the assembly to be activated.", [e description]);
}
}

- (void)test_before_activation_raises_exception_when_invoking_subscription
{
@try {
Expand Down Expand Up @@ -226,4 +217,32 @@ - (void)test_nil_definition_with_injection_hooks
}
}

- (void)test_before_activation_preattaches_infrastructure_components
{
MiddleAgesAssembly *assembly = [MiddleAgesAssembly assembly];

TyphoonPatcher *patcher = [TyphoonPatcher new];
[assembly attachDefinitionPostProcessor:patcher];

TyphoonInstancePostProcessorMock *instancePostProcessor = [TyphoonInstancePostProcessorMock new];
[assembly attachInstancePostProcessor:instancePostProcessor];

NSNullTypeConverter *typeConverter = [NSNullTypeConverter new];
[assembly attachTypeConverter:typeConverter];

TyphoonBlockComponentFactory *factory = [[TyphoonBlockComponentFactory alloc] initWithAssembly:assembly];

NSArray *attachedDefinitionPostProcessors = factory.definitionPostProcessors;
BOOL isPatcherAttached = [attachedDefinitionPostProcessors containsObject:patcher];

NSArray *attachedInstancePostProcessors = factory.instancePostProcessors;
BOOL isInstancePostProcessorAttached = [attachedInstancePostProcessors containsObject:instancePostProcessor];

BOOL isTypeConverterAttached = [factory.typeConverterRegistry converterForType:[typeConverter supportedType]] != nil;

XCTAssertTrue(isPatcherAttached);
XCTAssertTrue(isInstancePostProcessorAttached);
XCTAssertTrue(isTypeConverterAttached);
}

@end
4 changes: 2 additions & 2 deletions Tests/Factory/Internal/TyphoonBlockComponentFactoryTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ - (void)setUp
internalProcessorsCount = [[_componentFactory definitionPostProcessors] count];

TyphoonConfigPostProcessor *processor = [TyphoonConfigPostProcessor forResourceNamed:@"SomeProperties.properties"];
[_componentFactory attachPostProcessor:processor];
[_componentFactory attachDefinitionPostProcessor:processor];

_exceptionTestFactory = [[TyphoonBlockComponentFactory alloc] initWithAssembly:[ExceptionTestAssembly assembly]];
_circularDependenciesFactory = [[TyphoonBlockComponentFactory alloc]
Expand Down Expand Up @@ -217,7 +217,7 @@ - (void)test_resolves_property_values
TyphoonComponentFactory *factory = [[TyphoonBlockComponentFactory alloc]
initWithAssembly:[TyphoonConfigAssembly assembly]];
TyphoonConfigPostProcessor *processor = [TyphoonConfigPostProcessor forResourceNamed:@"SomeProperties.properties"];
[factory attachPostProcessor:processor];
[factory attachDefinitionPostProcessor:processor];

Knight *knight = [factory componentForKey:@"knight"];
XCTAssertEqual(knight.damselsRescued, (NSUInteger)12);
Expand Down
Loading

0 comments on commit 4da05e0

Please sign in to comment.