NamedResolver 1.1.0
See the version list below for details.
dotnet add package NamedResolver --version 1.1.0
NuGet\Install-Package NamedResolver -Version 1.1.0
<PackageReference Include="NamedResolver" Version="1.1.0" />
paket add NamedResolver --version 1.1.0
#r "nuget: NamedResolver, 1.1.0"
// Install NamedResolver as a Cake Addin #addin nuget:?package=NamedResolver&version=1.1.0 // Install NamedResolver as a Cake Tool #tool nuget:?package=NamedResolver&version=1.1.0
NamedResolver
An abstraction that provide ability to use interface with multiple implementations or preconfigured instances in easy way using local ServiceLocator pattern.
Installing NamedResolver
You should install NamedResolver with NuGet:
Install-Package NamedResolver
Or via the .NET Core command line interface:
dotnet add package NamedResolver
Use cases
let's assume we have this:
public interface ISomeInterface {}
public class FirstImplementation : ISomeInterface {}
public class SecondImplementation : ISomeInterface {}
And we register like this:
services.AddScoped<ISomeInterface, FirstImplementation>();
services.AddScoped<ISomeInterface, SecondImplementation>();
And sometimes we need to resolve one of implementation of interface directly.
In most cases, for resolve, we inject IEnumerable<TInterface>
in our DependentClass
and then search using typeof(T).
public class DependentClass
{
private readonly ISomeInterface _firstImplementation;
public DependentClass(IEnumerable<ISomeInterface> implementations)
{
// in this case we always resolve from DI all implementations of ISomeInterface.
_firstImplementation =
implementations.SingleOrDefault(i => i.GetType() == typeof(FirstImplementation)) ??
throw new ArgumentNullException($"Cannot resolve instance of type {typeof(FirstImplementation).FullName}");
}
}
Also we can register to IServiceCollection our implementation without interface, and inject implementation into DependenentClass explicitly, but it is not good for unit testing:
services.AddScoped<FirstImplementation>();
services.AddScoped<SecondImplementation>();
public class DependentClass
{
private readonly ISomeInterface _firstImplementation;
public DependentClass(FirstImplementation firstImplementation)
{
_firstImplementation = firstImplementation;
}
}
Same with NamedResolver
services.AddNamed<ISomeInterface>(ServiceLifeTime.Scoped)
.Add<FirstImplementation>("First");
.Add<SecondImplementation>("Second");
public class DependentClass
{
private readonly ISomeInterface _firstImplementation;
public DependentClass(INamedResolver<ISomeInterface> resolver)
{
_firstImplementation = resolver.Get("First");
}
}
Features:
Default instance:
public class DefaultImplementation : ISomeInterface {}
services.AddNamed<ISomeInterface>(ServiceLifeTime.Scoped)
.Add<FirstImplementation>("First");
.Add<SecondImplementation>("Second")
.Add<DefaultImplementation>(); // default - without name parameter
public class DependentClass
{
private readonly ISomeInterface _defaultImplementation;
public DependentClass(ISomeInterface someInterface)
{
// DefaultImplementation would be injected
_defaultImplementation = someInterface;
}
}
Preconfigured instances
services.AddNamed<ISomeInterface>(ServiceLifeTime.Scoped)
.Add<FirstImplementation>("FirstUseCase", _ => new FirstImplementation("FirstUseCase"));
.Add<FirstImplementation>("SecondUseCase", _ => new FirstImplementation("SecondUseCase"));
Resolve all
public class DependentClass
{
private readonly IEnumerable<ISomeInterface> _implementations;
private readonly IEnumerable<ISomeInterface> _fromSampleNamespace;
private readonly IEnumerable<(string name, ISomeInterface instance)> _implementationsWithNames;
public DependentClass(INamedResolver<ISomeInterface> resolver)
{
_implementations = resolver.GetAll();
_implementationsWithNames = resolver.GetAllWithNames();
_fromSampleNamespace = resolver.GetAll(t => t.Namespace.StartsWith("Sample"));
}
}
Contribute
Feel free for creation issues, or PR 😃
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 is compatible. netcoreapp2.2 is compatible. netcoreapp3.0 is compatible. netcoreapp3.1 is compatible. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETCoreApp 2.1
-
.NETCoreApp 2.2
-
.NETCoreApp 3.0
-
.NETCoreApp 3.1
-
.NETStandard 2.0
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.