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

Exception with reason: 'Key is already registered.' #554

Open
pinchukvd opened this issue Mar 22, 2017 · 5 comments
Open

Exception with reason: 'Key is already registered.' #554

pinchukvd opened this issue Mar 22, 2017 · 5 comments

Comments

@pinchukvd
Copy link

pinchukvd commented Mar 22, 2017

I have two properties in AppAssembly - SearchModuleAssembly and FavoritesModuleAssembly. AppAssembly, SearchModuleAssembly, FavoritesModuleAssembly are initial assemblies.
It's throwing an exception on run "reason: 'Key 'router' is already registered.'".

@interface AppAssembly : TyphoonAssembly
@property (strong, nonatomic) SearchModuleAssembly *searchModuleAssembly;
@property (strong, nonatomic) FavoritesModuleAssembly *favoritesModuleAssembly;
@implementation SearchModuleAssembly
-(UIViewController *)view
{
    return [TyphoonDefinition withClass:[SearchVC class] configuration:^(TyphoonDefinition *definition) {
        [definition useInitializer:@selector(initWithClassNib)];
        [definition injectProperty:@selector(viewModel) with:[self viewModel]];
    }];
}

-(id<ViewModelProtocol>)viewModel
{
    return [TyphoonDefinition withClass:[SearchViewModel class] configuration:^(TyphoonDefinition *definition) {
        [definition injectProperty:@selector(router) with:[self router]];
    }];
}

-(id<RouterProtocol>)router
{
    return [TyphoonDefinition withClass:[SearchRouter class] configuration:^(TyphoonDefinition *definition) {
        [definition injectProperty:@selector(viewController) with:[self view]];
    }];
}
@implementation FavoritesModuleAssembly
-(UIViewController *)view
{
    return [TyphoonDefinition withClass:[FavoritesVC class] configuration:^(TyphoonDefinition *definition) {
        [definition useInitializer:@selector(initWithClassNib)];
        [definition injectProperty:@selector(viewModel) with:[self viewModel]];
    }];
}

-(id<ViewModelProtocol>)viewModel
{
    return [TyphoonDefinition withClass:[FavoritesViewModel class] configuration:^(TyphoonDefinition *definition) {
        [definition injectProperty:@selector(router) with:[self router]];
    }];
}

-(id<RouterProtocol>)router
{
    return [TyphoonDefinition withClass:[FavoritesRouter class] configuration:^(TyphoonDefinition *definition) {
        [definition injectProperty:@selector(viewController) with:[self view]];
    }];
}

@pinchukvd pinchukvd reopened this Mar 22, 2017
@jasesuperhero
Copy link

I found a solution for this problem. We can change definition.key from configuration. It will look like this:

return [TyphoonDefinition withClass:[FavoritesRouter class] configuration:^(TyphoonDefinition *definition) {
        definition.key = @"FavoritesModuleAssembly_router"; 
        [definition injectProperty:@selector(viewController) with:[self view]];
    }];

The solution seems to be ugly because we’ll have to change the definition.key on all definitions.
@etolstoy Is it possible to delimit definitions on a namespaces, using typhoon functionality?
In this article, you mentioned that the key is compound and consists of a random string and the name of the method. What has changed?

@jasperblues
Copy link
Member

@jasesuperhero You can also consider namespacing your methods:

favoritesRouter
SearchRouter

@jasesuperhero
Copy link

@jasperblues Yeah, sure. But if we use TyphoonAssemblies for MVVM or VIPER modules creation we’ll have problems with using common protocol or class with the same names in one module. Every VIPER module has view, presenter, interactor, also we have some runtime magic using the exact names. For example:

@protocol MVVMAssebly <NSObject>

@required
- (id)model;
- (id)view;
- (id)viewModel;

@end

@jasperblues
Copy link
Member

Relates to: #446

@jasesuperhero
Copy link

jasesuperhero commented Jun 28, 2017

In #446 pr we got the opportunity to create definitions with configs, that has specific definition.key. But in current case it's not useful, because we want to create definitions with uniq keys in range of one assembly and using configuration in code. I found the method -setDefinitionKeyRandomlyIfNeeded, that can resolve current problem, but it will called, if key.length == 0. it's not very comfortable to set empty key in all definitions. Do you have any ideas? Maybe we can create pr with new initializers for definition, that set key to empty.

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

3 participants