Common: Check that injected types are subtypes of interfaces

This commit is contained in:
Mike Salvatore 2022-04-27 09:18:55 -04:00
parent 77753aca3f
commit 1e9627470c
2 changed files with 23 additions and 1 deletions

View File

@ -29,7 +29,12 @@ class DIContainer:
raise TypeError(
"Expected a class, but received an instance of type "
f'"{concrete_type.__class__.__name__}"; Pass a class, not an instance, to '
"register(), or use register_instance() instead."
"register(), or use register_instance() instead"
)
if not issubclass(concrete_type, interface):
raise TypeError(
f'Class "{concrete_type.__name__}" is not a subclass of {interface.__name__}'
)
self._type_registry[interface] = concrete_type
@ -42,6 +47,12 @@ class DIContainer:
:param interface: An interface or abstract base class that other classes depend upon
:param instance: An instance (object) of a type that implements `interface`
"""
if not isinstance(instance, interface):
raise TypeError(
f'The provided instance of type "{instance.__class__.__name__}" '
f"is not an instance of {interface.__name__}"
)
self._instance_registry[interface] = instance
DIContainer._del_key(self._type_registry, interface)

View File

@ -270,3 +270,14 @@ def test_register_instance_as_type(container):
service_a_instance = ServiceA()
with pytest.raises(TypeError):
container.register(IServiceA, service_a_instance)
def test_register_conflicting_type(container):
with pytest.raises(TypeError):
container.register(IServiceA, ServiceB)
def test_register_instance_with_conflicting_type(container):
service_b_instance = ServiceB()
with pytest.raises(TypeError):
container.register_instance(IServiceA, service_b_instance)