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

Preattaching infrastructure components #444

Merged
merged 5 commits into from
Nov 8, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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