IGet.GetAll
1.0.1
See the version list below for details.
dotnet add package IGet.GetAll --version 1.0.1
NuGet\Install-Package IGet.GetAll -Version 1.0.1
<PackageReference Include="IGet.GetAll" Version="1.0.1" />
paket add IGet.GetAll --version 1.0.1
#r "nuget: IGet.GetAll, 1.0.1"
// Install IGet.GetAll as a Cake Addin #addin nuget:?package=IGet.GetAll&version=1.0.1 // Install IGet.GetAll as a Cake Tool #tool nuget:?package=IGet.GetAll&version=1.0.1
IGet.GetAll
Extends IGet. Get an IEnumerable of class instances (with their dependencies injected) via i.GetAll<IMyInterface>()
or i.GetAll<MyBaseClass>()
.
Idea: create a generic notification publisher and use it like i.Get<NotificationPublisher<NotificationA>>().Publish(notification)
instead of mediatR.Publish(notification)
.
using IGetAll;
serviceCollection.AddIGet();
serviceCollection.AddIGetAll(new [] { typeof(Startup).Assembly, ... });
Why?
IGet gets single classes, but cannot provide multiple in one call. If you like MediatR's INotification-INotificationHandler combination then you will probably feel the need for something that automatically collects INotificationHandlers - that is one of the things that i.GetAll<T>()
can do - it has the following benefits:
- you declare whatever interfaces and base classes you like; this package does not force you to use pre-defined interfaces.
- after
i.GetAll<T>()
you explicitly show how you handle exceptions, making your code easier to understand. - after
i.GetAll<T>()
you explicitly show that you useTask.WhenAll
orforeach
withawait
(or synchronous code).
Also note: no matter how complicated your interfaces or generic base classes are - think about IMyInterface<SomeClass, NestedBaseClass<AnotherClass, AndMore>>
- no additional configuration is needed.
About performance
Each time you use i.GetAll<T>()
for a new type T
the collected Type[]
is stored in a ConcurrentDictionary
so that when you call i.GetAll<T>()
next time for the same type T
, no assembly scanning is done.
Example
Declare an interface you like:
public interface INotificationHandler<TNotification>
{
Task HandleAsync(TNotification notification, CancellationToken cancellationToken);
}
Implement the interface:
public class NotificationA { }
public class HandlerA1 : INotificationHandler<NotificationA>
{
private readonly ILogger<HandlerA1> _logger;
public HandlerA1(ILogger<HandlerA1> logger)
{
_logger = logger;
}
public async Task HandleAsync(NotificationA notification, CancellationToken cancellationToken)
{
// do stuff
}
}
public class HandlerA2 : INotificationHandler<NotificationA>
{
private readonly IConnectionFactory _connectionFactory;
public HandlerA2(IConnectionFactory connectionFactory)
{
_connectionFactory = connectionFactory;
}
public async Task HandleAsync(NotificationA notification, CancellationToken cancellationToken)
{
// do stuff
}
}
public class NotificationB { }
public class HandlerB1 : INotificationHandler<NotificationB>
{
private readonly ILogger<Handler1> _logger;
public HandlerB1(ILogger<Handler1> logger)
{
_logger = logger;
}
public async Task HandleAsync(NotificationB notification, CancellationToken cancellationToken)
{
// do stuff
}
}
Create a generic notification publisher for all your notification types:
public class NotificationPublisher<TNotification> where TNotification : notnull
{
private readonly ILogger _logger;
private readonly IGet i;
public NotificationPublisher(IGet iget, ILogger logger)
{
_logger = logger;
i = iget;
}
public async Task Publish(TNotification notification, CancellationToken cancellationToken = default)
{
foreach (var handler in i.GetAll<INotificationHandler<TNotification>>())
{
try
{
await handler.HandleAsync(notification, cancellationToken);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in {handlerType} for {notificationKeyValuePairs}.", handler.GetType().FullName, notification.ToKeyValuePairsString());
}
}
}
}
Publish notifications:
// invokes HandlerA1 and HandlerA2:
await i.Get<NotificationPublisher<NotificationA>>().Publish(notificationA);
// invokes HandlerB1:
await i.Get<NotificationPublisher<NotificationB>>().Publish(notificationB);
Try it out
The examples above give an idea of how you can be creative with IGet and IGet.GetAll. Share your own examples online to spread the word about IGet and IGet.GetAll.
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 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.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. |
-
.NETStandard 2.0
- IGet (>= 1.1.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
v1.0.*: updates of the readme.