Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add generic overloads for TryResolveNamed and TryResolveKeyed #1287

Merged
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
66 changes: 66 additions & 0 deletions src/Autofac/ResolutionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,39 @@ public static bool TryResolve(this IComponentContext context, Type serviceType,
return context.TryResolveService(new TypedService(serviceType), NoParameters, out instance);
}

/// <summary>
/// Try to retrieve a service from the context.
/// </summary>
/// <typeparam name="T">The service type to resolve.</typeparam>
/// <param name="context">The context from which to resolve the service.</param>
/// <param name="serviceKey">The key of the service to resolve.</param>
/// <param name="instance">The resulting component instance providing the service, or null.</param>
/// <returns>
/// True if a component providing the service is available.
/// </returns>
/// <exception cref="DependencyResolutionException"/>
public static bool TryResolveKeyed<T>(this IComponentContext context, object serviceKey, [NotNullWhen(returnValue: true)] out T? instance)
where T : class
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

if (context.TryResolveKeyed(serviceKey, typeof(T), out object? component))
{
instance = CastInstance<T>(component);

return true;
}
else
{
instance = default;

return false;
}
}

/// <summary>
/// Try to retrieve a service from the context.
/// </summary>
Expand All @@ -973,6 +1006,39 @@ public static bool TryResolveKeyed(this IComponentContext context, object servic
return context.TryResolveService(new KeyedService(serviceKey, serviceType), NoParameters, out instance);
}

/// <summary>
/// Try to retrieve a service from the context.
/// </summary>
/// <typeparam name="T">The service type to resolve.</typeparam>
/// <param name="context">The context from which to resolve the service.</param>
/// <param name="serviceName">The name of the service to resolve.</param>
/// <param name="instance">The resulting component instance providing the service, or null.</param>
/// <returns>
/// True if a component providing the service is available.
/// </returns>
/// <exception cref="DependencyResolutionException"/>
public static bool TryResolveNamed<T>(this IComponentContext context, string serviceName, [NotNullWhen(returnValue: true)] out T? instance)
where T : class
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

if (context.TryResolveNamed(serviceName, typeof(T), out object? component))
{
instance = CastInstance<T>(component);

return true;
}
else
{
instance = default;

return false;
}
}

/// <summary>
/// Try to retrieve a service from the context.
/// </summary>
Expand Down
46 changes: 46 additions & 0 deletions test/Autofac.Test/ResolutionExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,51 @@ public void RegisterPropertyWithExpressionFieldExceptions()
Assert.Throws<ArgumentOutOfRangeException>(() =>
builder.RegisterType<WithProps>().WithProperty(x => x._field, a));
}

[Fact]
public void WhenServiceIsRegistered_TryResolveNamedReturnsTrue()
{
const string name = "name";

var cb = new ContainerBuilder();
cb.RegisterType<object>().Named<object>(name);

var container = cb.Build();

Assert.True(container.TryResolveNamed<object>(name, out var o));
Assert.NotNull(o);
}

[Fact]
public void WhenServiceIsNotRegistered_TryResolveNamedReturnsFalse()
{
var container = Factory.CreateEmptyContainer();

Assert.False(container.TryResolveNamed<object>("name", out var o));
Assert.Null(o);
}

[Fact]
public void WhenServiceIsRegistered_TryResolveKeyedReturnsTrue()
{
var key = new object();

var cb = new ContainerBuilder();
cb.RegisterType<object>().Keyed<object>(key);

var container = cb.Build();

Assert.True(container.TryResolveKeyed<object>(key, out var o));
Assert.NotNull(o);
}

[Fact]
public void WhenServiceIsNotRegistered_TryResolveKeyedReturnsFalse()
{
var container = Factory.CreateEmptyContainer();

Assert.False(container.TryResolveKeyed<object>("name", out var o));
Assert.Null(o);
}
}
}