Skip to content

Advanced InComing Handlers

MohammadReza edited this page Jul 21, 2021 · 7 revisions

First of all! Why advanced?

There're some reasons that makes them advanced at least in compare with others. let's review some of them:

  • This type of incoming handlers are easier and cleaner to user ( especially With auto add incoming feature! )

  • This handler are some kind of builder for a sub-handler which means they do not contain an instance of a handler but a Type

  • They're better in performance since the instance in not created till they are needed and they will be disposed when handling is done!

  • and Most of all: they can use dependencies tree! and all of these will created if they are needed (An advanced handler is needed when an update passed their filters!) and all of the dependencies in tree will be disposed when handling process is done!

These creating instance of dependencies are done with Reflection and built-in stuff. no DI third-party library or something like that is used.

You can always use any combination of any kind of handlers ( as Flamingo trying to keep everything customizable )

How to

To setup an advanced handler, you should create an incoming handler class which inherence from AdvInComingFish<T> where T is an incoming update type ( Message for example )

You should place this call in {ProjectName}.InComings.Messages ( for message handlers) if you want to use auto add handlers feature!

using Flamingo.Fishes.Advanced.InComingHandlers;

namespace MyBot.InComings.Messages
{
    public class MyAdvHandler: AdvInComingFish<Message>
    {
        public MyAdvHandler()
        {

        }
    }
}

Now is the time to add your Filters here!

using Flamingo.Fishes.Advanced.InComingHandlers;
using Flamingo.Attributes.Filters.Messages;

namespace MyBot.InComings.Messages
{
    [CommandFilter("start")]
    [ChatTypeFilter(FlamingoChatType.Private)]
    public class MyAdvHandler: AdvInComingFish<Message>
    {
        public MyAdvHandler()
        {

        }
    }
}

Remember you can always create your own Filters! Attribute on none.

Then override GetEatenWrapper method the way you like!

using Flamingo.Fishes.Advanced.InComingHandlers;
using Flamingo.Attributes.Filters.Messages;
using Flamingo.Condiments.Extensions;
using System.Threading.Tasks;
using Telegram.Bot.Types;

namespace MyBot.InComings.Messages
{
    [CommandFilter("start")]
    [ChatTypeFilter(FlamingoChatType.Private)]
    public class MyAdvHandler: AdvInComingFish<Message>
    {
        public MyAdvHandler()
        {

        }

        protected override async Task GetEatenWrapper(Message inComing)
        {
            await Cdmt.ReplyText("Flamingo Started!");
        }
    }
}

And that's all for now! Don't forget to call AutoAddInComings() after creating Flamingo instance in programs main method.

static async Task Main()
{
    var flamingo = new FlamingoCore()
        // Add all incoming handler in 'InComings.{UpdateTypes}' namesspaces
        // Like 'InComings.Messages' for message incoming handlers
        .AutoAddInComings()
        .InitBot("BOT_TOKEN_HERE", true)

    // Start receiving updates and blocks current thread
    await flamingo.Fly(errorHandler: Err);
}

How to add dependencies?

Assume MyDbContext is what you need here.

using Flamingo.Fishes.Advanced.InComingHandlers;
using Flamingo.Attributes.Filters.Messages;
using Flamingo.Condiments.Extensions;
using System.Threading.Tasks;
using Telegram.Bot.Types;

namespace MyBot.InComings.Messages
{
    [CommandFilter("start")]
    [ChatTypeFilter(FlamingoChatType.Private)]
    public class MyAdvHandler: AdvInComingFish<Message>
    {
        private readonly MyDbContext _context;

        [AdvancedHandlerConstructor]
        public MyAdvHandler(MyDbContext context)
        {
            _context = context;
        }

        protected override async Task GetEatenWrapper(Message inComing)
        {
            await Cdmt.ReplyText("Flamingo Started!");

            _context.SomethingToDoWith();
        }
    }
}

[AdvancedHandlerConstructor] attribute is required! and all parameters in the constructor that has this attribute will automatically created ( Whit their parameters-less constructor ) If this parameter is also depended on some classes, you should add [AdvancedHandlerConstructor] on the target constructor!

Here we assume that MyDbContext has parameters-less constructor.

What if dependency is also depended

If MyDbContext has parameters in the constructor, then you should have something like this:

public class MyDbContext
{
    [AdvancedHandlerConstructor]
    public MyDbContext(RequireOn requirement)
    {

    }
}

Manual add incoming

You can also add adv handlers manually if preferred!

// Filters can be added when creating incoming handler class as attributes
var carrier = flamingo.AddAdvancedInComing<Message, MyAdvHandler>(
    new CommandFilter("count"));

// Use this if you didn't use [AdvancedHandlerConstructor]
carrier.Require<FlamingoContext>()
    .Require<Something>();

As you can see, requirements should be added manually too

What’s Next?

Flamingo Framework written in pure c#, install from Nuget

Clone this wiki locally