public void Use(UpdateProcessingDelegate middlewareDelegate) { if (middlewareDelegate == null) { throw new ArgumentNullException(nameof(middlewareDelegate)); } _updateProcessingDelegates.Push(middlewareDelegate); }
// 共通処理 private void CommonUpdate(UpdateProcessingDelegate onUpdate) { for (int i = 0; i < m_ringBuffer.Length; i++) { if (!m_ringBuffer[i].gameObject.activeSelf) { continue; } onUpdate(m_ringBuffer[i]); } }
public UpdateProcessingDelegate Build() { //For each new iteration and each middleware from stack processingDelegate_OfIteration will contain delegate to execute //all next middleware. //"next" delegate for current iteration. Started with empty delegate for last middleware. UpdateProcessingDelegate processingDelegate_OfIteration = async(UpdateContext ctx, Func <Task> nextFunc) => { }; while (_updateProcessingDelegates.Count > 0) { var prevProcessingDelegate = processingDelegate_OfIteration; var currentProcessingDelegate = _updateProcessingDelegates.Pop(); processingDelegate_OfIteration = async(UpdateContext ctx, Func <Task> mostNext) => { Func <Task> next = async() => { await prevProcessingDelegate.Invoke(ctx, mostNext); }; //Force exit. if (ctx.ForceExitRequested) { return; } //Execute current. await currentProcessingDelegate.Invoke(ctx, next); }; } //Just add some checks. UpdateProcessingDelegate res = async(UpdateContext ctx, Func <Task> next) => { if (ctx == null) { throw new ArgumentNullException(nameof(ctx), "Null context passed to UpdateProcessingDelegate."); } if (next == null) { throw new ArgumentNullException(nameof(next), "Null 'next' passed to UpdateProcessingDelegate."); } await processingDelegate_OfIteration.Invoke(ctx, next); }; return(res); }
/// <summary> /// /// </summary> /// <param name="disposeServices">Default is true.</param> public async void Dispose(bool disposeServices) { if (IsDisposed) { return; } await Stop(); if (disposeServices) { //Dispose singletones that registered to be disposed. foreach (var type in _forDispose) { IDisposable serviceToDispose = null; try { serviceToDispose = Services.GetService(type) as IDisposable; } catch { } serviceToDispose?.Dispose(); } (Services as IDisposable)?.Dispose(); } Services = null; BotContext = null; _updateProcessingDelegate = null; IsDisposed = true; _updatesReceiver.BotManagerDisposed(); GC.Collect(); _logger.LogTrace(nameof(BotManager) + " disposed."); }
/// <summary> /// Execute initialization callbacks and build pipeline. /// <para></para> /// Called automatically on Start() first call. /// </summary> /// <param name="serviceProvider"> /// If not null - will use passed provider instead builded from service collection. /// Useful when you wan't to set same container in ASP.NET and here. /// </param> /// <param name="updatesReceiver"> /// Use it to customize how bot receiving updates. /// Default is <see cref="PollingUpdatesReceiver"/> and subscribe on <see cref="ITelegramBotClient.OnUpdate"/>. /// It will set webhook string empty, to enable polling. /// </param> public void Setup(IServiceProvider serviceProvider = null, IUpdatesReceiver updatesReceiver = null) { //?Why use IUpdatesReceiver? Why not just make ProcessUpdate method public? //Was decided to use interface with event to wrote more "infrastructure" code in BotManager. lock (_setupLocker) { try { if (_isSetup) { return; } //Init bot context. var botInfo = _bot.GetMeAsync().Result; BotContext = new BotClientContext(_bot, botInfo); //Set UpdateReceiver. _updatesReceiver = updatesReceiver ?? new PollingUpdatesReceiver(); _updatesReceiver.Init(this); //Build service provider. string providerIndentifierForLog; if (serviceProvider == null) { Services = _serviceCollectionWrapper.Services.BuildServiceProvider(); providerIndentifierForLog = "ServiceProvider builded from ServiceCollection."; } else { Services = serviceProvider; providerIndentifierForLog = "Passed ServiceProvider used."; } _serviceCollectionWrapper = null; //Resolve services needed for BotManager. ResolveBotManagerServices(); _logger.LogTrace("Services initialized. " + providerIndentifierForLog); //Not implemented. IPipelineBuilder pipelineBuilder = new PipelineBuilder(Services); //Register middleware. UseMandatoryMiddleware(pipelineBuilder); if (_pipelineBuilderAction == null) { throw new NullReferenceException( "Can`t init without pipeline builder configure action. " + "Probably ConfigureBuilder wasn't invoked." ); } _pipelineBuilderAction.Invoke(pipelineBuilder); _pipelineBuilderAction = null; //Build pipeline. _updateProcessingDelegate = pipelineBuilder.Build(); _isSetup = true; _logger.LogTrace("Pipeline builded."); } catch (Exception ex) { var exception = new TelegramAspException("BotManager setup exception.", ex); if (_logger == null) { Debug.WriteLine(exception.ToString()); } else { _logger.LogError(exception, ""); } throw exception; } } }