-
Notifications
You must be signed in to change notification settings - Fork 2
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
Detect and validate duplicate registrations within an Assembly #199
Conversation
extension ConfigurationSet { | ||
|
||
private struct Key: Hashable { | ||
let service: String |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think both arguments
and ifConfigCondition
are needed in this key for uniqueness. ifConfigCondition is a little more complex as per the following code.
# if DEBUG
container.register(Service.self, factory: DebugService.init)
#endif
# if RELEASE
container.register(Service.self, factory: ReleaseService.init)
#endif
container.register(Service.self, factory: DuplicateService.init)
The DEBUG and RELEASE configurations don't clash (but there's no way to know that from code that those are exclusive) but both clash with the registration that isn't wrapped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah thanks yes i'll update
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to include arguments. Still need to work on the ifConfigCondition
check as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also i realized i need to separate the assemblies by TargetResolver
because we have shadowed registrations for Entities
registrationCount += 1 | ||
registrationSet.insert(Key(service: registration.service, name: registration.name)) | ||
|
||
guard registrationCount == registrationSet.count else { | ||
throw ConfigurationSetParsingError.detectedDuplicateRegistration( | ||
service: registration.service, | ||
name: registration.name | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: registrationCount
could be removed by checking if the registrationSet contains the key already
registrationCount += 1 | |
registrationSet.insert(Key(service: registration.service, name: registration.name)) | |
guard registrationCount == registrationSet.count else { | |
throw ConfigurationSetParsingError.detectedDuplicateRegistration( | |
service: registration.service, | |
name: registration.name | |
) | |
} | |
let key = Key(service: registration.service, name: registration.name) | |
guard !registrationSet.contains(key) else { | |
throw ConfigurationSetParsingError.detectedDuplicateRegistration( | |
service: registration.service, | |
name: registration.name | |
) | |
} | |
registrationSet.insert(key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks safe but I'm not sure if there are any edge cases in cash-ios that might prevent building.
cf34d18
to
b9205eb
Compare
b9205eb
to
c9f5c3d
Compare
We are able to detect duplicates from within a single module at parse/compile time, so it will be good to fail early and provide an error to the developer.
c9f5c3d
to
e3c6df4
Compare
Ok i updated to add support for assemblies with multiple different TargetResolvers within the same configuration set. Ran against cash-ios and it has detected some duplicates. |
We are able to detect duplicates from within a single module at parse/compile time, so it will be good to fail early and provide an error to the developer.