Effects Composition¶
The NotifyModule declares two [EffectsModule] targets — INotificationChannel for sending and INotificationStore for persistence — generating Eff<RT, T> effect methods for both.
Capability Interfaces¶
public interface IHasNotificationChannel
{
INotificationChannel NotificationChannel { get; }
}
public interface IHasNotificationStore
{
INotificationStore NotificationStore { get; }
}
Effect Methods¶
Channel (sending)¶
public static partial class NotifyModule
{
public static partial class Channel
{
public static Eff<RT, Unit> SendAsync<RT>(Notification notification)
where RT : IHasNotificationChannel => ...
public static Eff<RT, Unit> SendManyAsync<RT>(IReadOnlyList<Notification> notifications)
where RT : IHasNotificationChannel => ...
}
}
Store (persistence + queries)¶
public static partial class NotifyModule
{
public static partial class Store
{
public static Eff<RT, Unit> SaveAsync<RT>(Notification notification)
where RT : IHasNotificationStore => ...
public static Eff<RT, IReadOnlyList<StoredNotification>> GetAsync<RT>(
string recipientId, bool unreadOnly = false, int offset = 0, int limit = 20)
where RT : IHasNotificationStore => ...
public static Eff<RT, Unit> MarkReadAsync<RT>(string notificationId)
where RT : IHasNotificationStore => ...
public static Eff<RT, Unit> MarkAllReadAsync<RT>(string recipientId)
where RT : IHasNotificationStore => ...
public static Eff<RT, int> GetUnreadCountAsync<RT>(string recipientId)
where RT : IHasNotificationStore => ...
}
}
Effect Pipeline Examples¶
Send + persist a notification¶
var notifyUser =
from _ in NotifyModule.Channel.SendAsync<AppRuntime>(new Notification
{
RecipientId = userId,
Title = "Order Shipped",
Body = $"Your order #{orderId} has shipped!",
Type = "order_update"
})
from __ in NotifyModule.Store.SaveAsync<AppRuntime>(notification)
select unit;