Skip to content

Commit

Permalink
Update behavior of ObjectContainer.IsRegistered() to check base con…
Browse files Browse the repository at this point in the history
…tainer for registrations (#367)

* Adding IsRegisteredAtAnyLevel() to ObjectContainer

* Update CHANGELOG

* Update registration method summaries in IObjectContainer

* PR feedback: Change behavior of IsRegistered()

* Update changelog

---------

Co-authored-by: Steven Ryland <[email protected]>
  • Loading branch information
DrEsteban and Steven Ryland authored Feb 3, 2025
1 parent 810100b commit 63cd706
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Improve code-behind feature file compilation speed (#336)
* Improve parameter type naming for generic types (#343)
* Reduced MsBuild log output and consistent use of [Reqnroll] prefix (#381)
* Update behavior of `ObjectContainer.IsRegistered()` to check base container for registrations, to match `Resolve()` behavior (#367)

## Bug fixes:
* MsTest: Only use TestContext for output and not Console.WriteLine (#368)
Expand Down
6 changes: 3 additions & 3 deletions Reqnroll/BoDi/IObjectContainer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;

namespace Reqnroll.BoDi;
Expand Down Expand Up @@ -109,15 +109,15 @@ public interface IObjectContainer : IDisposable
IEnumerable<T> ResolveAll<T>() where T : class;

/// <summary>
/// Determines whether the interface or type is registered optionally with the specified name.
/// Determines whether the interface or type is registered in the container, optionally with the specified name.
/// </summary>
/// <typeparam name="T">The interface or type.</typeparam>
/// <param name="name">The name or <c>null</c>.</param>
/// <returns><c>true</c> if the interface or type is registered; otherwise <c>false</c>.</returns>
bool IsRegistered<T>(string name = null);

/// <summary>
/// Determines whether the interface or type is registered with the specified name.
/// Determines whether the interface or type is registered in the container, optionally with the specified name.
/// </summary>
/// <param name="type">The interface or type.</param>
/// <param name="name">The name.</param>
Expand Down
15 changes: 14 additions & 1 deletion Reqnroll/BoDi/ObjectContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -487,13 +487,26 @@ public IStrategyRegistration RegisterFactoryAs(Delegate factoryDelegate, Type in
return factoryRegistration;
}

/// <inheritdoc/>
public bool IsRegistered<T>(string name = null) => IsRegistered(typeof(T), name);

/// <inheritdoc/>
public bool IsRegistered(Type type, string name = null)
{
var keyToResolve = new RegistrationKey(type, name);

return _registrations.ContainsKey(keyToResolve);
if (_registrations.ContainsKey(keyToResolve))
{
return true;
}
else if (BaseContainer != null)
{
// Recursively check the base container
return BaseContainer.IsRegistered(type, name);
}

// We are at the top of the container hierarchy and the registration is not found
return false;
}

// ReSharper disable once UnusedParameter.Local
Expand Down
74 changes: 74 additions & 0 deletions Tests/Reqnroll.RuntimeTests/BoDi/IsRegisteredTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ public void ShouldReturnFalseIfTypeNotRegistered()
isRegistered.Should().BeFalse();
}

[Fact]
public void ShouldReturnFalseIfTypeNotRegisteredWithParent()
{
// given
var parentContainer = new ObjectContainer();
var container = new ObjectContainer(parentContainer);

// then
bool isRegistered = container.IsRegistered<SimpleClassWithDefaultCtor>();
isRegistered.Should().BeFalse();
}

[Fact]
public void ShouldReturnTrueIfInterfaceRegistered()
{
Expand Down Expand Up @@ -59,5 +71,67 @@ public void ShouldReturnTrueIfTypeRegistered()

isRegistered.Should().BeTrue();
}

[Fact]
public void ShouldReturnTrueIfTypeRegisteredInParent()
{
// given
var grandparentContainer = new ObjectContainer();
var parentContainer = new ObjectContainer(grandparentContainer);
var container = new ObjectContainer(parentContainer);

// when
parentContainer.RegisterInstanceAs(new SimpleClassWithDefaultCtor());

// then
bool isRegistered = container.IsRegistered<SimpleClassWithDefaultCtor>();
isRegistered.Should().BeTrue();

isRegistered = parentContainer.IsRegistered<SimpleClassWithDefaultCtor>();
isRegistered.Should().BeTrue();

isRegistered = grandparentContainer.IsRegistered<SimpleClassWithDefaultCtor>();
isRegistered.Should().BeFalse();
}

[Fact]
public void ShouldReturnTrueIfTypeRegisteredInGrandparent()
{
// given
var grandparentContainer = new ObjectContainer();
var parentContainer = new ObjectContainer(grandparentContainer);
var container = new ObjectContainer(parentContainer);

// when
grandparentContainer.RegisterInstanceAs(new SimpleClassWithDefaultCtor());

// then
bool isRegistered = container.IsRegistered<SimpleClassWithDefaultCtor>();
isRegistered.Should().BeTrue();

isRegistered = parentContainer.IsRegistered<SimpleClassWithDefaultCtor>();
isRegistered.Should().BeTrue();

isRegistered = grandparentContainer.IsRegistered<SimpleClassWithDefaultCtor>();
isRegistered.Should().BeTrue();
}

[Fact]
public void ShouldReturnTrueIfRegisteredInSelfButFalseInParent()
{
// given
var parentContainer = new ObjectContainer();
var container = new ObjectContainer(parentContainer);

// when
container.RegisterInstanceAs(new SimpleClassWithDefaultCtor());

// then
bool isRegistered = container.IsRegistered<SimpleClassWithDefaultCtor>();
isRegistered.Should().BeTrue();

isRegistered = parentContainer.IsRegistered<SimpleClassWithDefaultCtor>();
isRegistered.Should().BeFalse();
}
}
}

0 comments on commit 63cd706

Please sign in to comment.