Quantcast
Channel: handlers – 100% Private Proxies – Fast, Anonymous, Quality, Unlimited USA Private Proxy!
Viewing all articles
Browse latest Browse all 10

Implicit Async and none async event handlers

$
0
0

I have implemented a event aggregator for our backend.

public class EventAggregator : IEventAggregator {     private readonly WeakReferenceList<object> _subscribers = new WeakReferenceList<object>();      public void Subscribe(object subscriber)     {         _subscribers.Add(subscriber);     }      public Task PublishAsync<T>(T message) where T : class     {         foreach (var handler in _subscribers.OfType<IHandle<T>>())             handler.Handle(message);          var handlers = _subscribers             .OfType<IHandleAsync<T>>()             .Select(s => s.HandleAsync(message))             .ToList();          if (handlers.Any()) return Task.WhenAll(handlers);         return Task.CompletedTask;     } } 

You can then choose to handle the events async or none async

None async

public class CreatedListener : IBusinessContextListener, IHandle<SavingChangesEvent> {     public CreatedListener(IEventAggregator eventAggregator)     {         eventAggregator.Subscribe(this);     }      public void Handle(SavingChangesEvent message)     {         foreach (var created in message.Context.Db.ChangeTracker.Entries<ICreated>().Where(c => c.State == EntityState.Added))         {             created.Entity.CreatedBy = message.Context.Username;             created.Entity.CreatedUTC = DateTime.UtcNow;         }     } } 

Async

public class AzureFileStorageExternalAdapter : IExternalPartAdapter, IHandleAsync<TransactionCommitedEvent> {     private readonly IBusinessContext _ctx;     private readonly List<CloudFile> _proccessedFiles;      public AzureFileStorageExternalAdapter(IBusinessContext ctx, IEventAggregator eventAggregator)     {         _ctx = ctx;         _proccessedFiles = new List<CloudFile>();         eventAggregator.Subscribe(this);     }       public Task<IEnumerable<byte[]>> ListResponses()     {         var folder = GetRemoteFolder($  "In:{_ctx.ExecutionContext.Name}");         var files = folder.ListFilesAndDirectories()             .Select(fi => fi as CloudFile)             .Where(file => file != null)             .ToList();          _proccessedFiles.AddRange(files);          return files             .Select(async file =>             {                 using (var stream = await file.OpenReadAsync())                 {                     using (var mem = new MemoryStream())                     {                         await stream.CopyToAsync(mem);                         mem.Position = 0;                         return mem.ToArray();                     }                 }             })             .WhenAll();     }       public Task HandleAsync(TransactionCommitedEvent message)     {         if (!_proccessedFiles.Any()) return Task.CompletedTask;          return _proccessedFiles             .Select(file => file.DeleteAsync())             .WhenAll();     } } 

Publisher has to be async even though only none async listeners are currently listenting

public class BusinessContext : IBusinessContextController, IDisposable {     private readonly IEventAggregator _eventAggregator;     private IDbContextTransaction _dbContextTransaction;      public BusinessContext(DbContext ctx, IEnumerable<IBusinessContextListener> ctxListeners, IEventAggregator eventAggregator)     {         _eventAggregator = eventAggregator;         Db = ctx;         if(ctxListeners == null) throw new ApplicationException("Do not remove this dependency, it ensures that listeners are awake");     }      public DbContext Db { get; }      public string Username { get; set; }      public ExecutionContext ExecutionContext { get; set; }      public async Task SaveChangesAsync()     {         await _eventAggregator.PublishAsync(new SavingChangesEvent(this));         await Db.SaveChangesAsync();     }      public async Task StartTransactionAsync()     {         if (_dbContextTransaction != null) return;          _dbContextTransaction = await Db.Database.BeginTransactionAsync();     }      public void Dispose()     {         _dbContextTransaction?.Dispose();     }      public Task CommitTransactionAsync()     {         _dbContextTransaction?.Commit();         return _eventAggregator.PublishAsync(new TransactionCommitedEvent());     }      public void RollbackTransaction()     {         _dbContextTransaction?.Rollback();     } } 

Bonus question the interface IBusinessContextListener is a empty markup interface that is only used to mark classes that have no other purpose than to be a event listener (Otherwise they would not be ‘awake’ and there Handle methods would not invoke. Solid design?

The post Implicit Async and none async event handlers appeared first on 100% Private Proxies - Fast, Anonymous, Quality, Unlimited USA Private Proxy!.


Viewing all articles
Browse latest Browse all 10

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>