rrousselGit / provider

InheritedWidgets, but simple
https://pub.dev/packages/provider
MIT License
5.11k stars 511 forks source link

Ripping off flutter_bloc... create a plugin instead #130

Closed warriorCoder closed 5 years ago

warriorCoder commented 5 years ago

While imitation is said to be the highest form of flattery, in software, the not invented here syndrome isn't good for the betterment of the community.

I fail to see why there needs to be yet ANOTHER package created to cram provider down people's throats just because it seems like the creator of this package doesn't want to play nice with others. (Yeah Remi... I'm calling you out on this one, show that you are really here for the community rather than your own selfish gain.)

To build unity and foster greater community it would be better, for yet another provider package, to create a plugin to flutter_bloc like can be shown here: https://pub.dev/packages/flutter_bloc_extensions

I'm calling on the creator of the provider package to do what's right for the community and stop this nonsense of fracturing packages rather than building on them and create a plugin for flutter_bloc instead of cramming everything into one monolithic package.

vshashi01 commented 5 years ago

I wonder of there are any real benefits in incorporating a bloc support directly into the provider package. Why does the creator feel so strongly about including it here in the provider package, it seems counterintuitive in the not reinventing the wheel. The only problem in using both the provider package, and flutter_bloc is the difference approaches in sending the object down the widget tree. Other than that I dont see an immediate problem in having both the packaged as a dependency in the same project. Does provider need to be more than a DI package even?

rrousselGit commented 5 years ago

EDIT:

Alright, after another long discussion with @felangel (thanks for his patience btw!), I'll just cancel that plan for now. I'm probably trying to have too much control over what provider users do.

For those who were interested in that binding, the code of the BlocProvider I wanted to publish is available here. It's


Hello! Thanks a lot for the issue. That's an important discussion that I agree we should have.

I share your concerns. Unironically, the reason we're having this discussion is because I want to stop that "nonsense of fracturing packages rather than building on them".

Here's a bit of history explaining everything that led me to this flutter_bloc branch that "forks" the flutter binding of http://github.com/felangel/bloc:

The community has a weird tendency to reinvent wrappers over InheritedWidget, which is one of the biggest cause of the following bug: https://stackoverflow.com/questions/52249578/how-to-deal-with-unwanted-widget-build, And provider is an attempt to finally solve that.

In the span of a year, I've discussed many times with different content creators (including Didier Boelens, Brian Egan, Pavan Podila, or more recently Felix Angelov) of the community about my desire to solve this issue.

In parallel, I opened a bunch of issues for similar discussions:

Somehow most of these discussions ended up agreeing at least partially that provider is a solution, as it currently is the only generic implementation (all the other available ones are specific to one architecture). And nowadays:

It's cool. But then came the IO talk, and I'm kind of mixed about it.

On one side, provider blew up, which will tremendously help the InheritedWidget unification.

On the other side, it got advertised as a scoped_model v2. I now hear on daily basis peoples migrating from Redux/BLoC to scoped_model using provider.

The problem is, I do not think that scoped_model is necessarily a good "go to" target. Its mutability combined with the sheer lack of DO/DON'T is basically sending the community onto a BLoC 2.0 world where they can do litteraly anything under the name of provider/scoped_model.


I don't want that. So I need some kind of damage control.

My discussions with flutter_bloc maintainers are part of that. flutter_bloc is one of the few architectures that I think are healthy, along with Mobx and raw widgets (using StatefulWidget or flutter_hook).

I spent easily 2 months discussing with them. But for some reasons, flutter_bloc maintainers decided against that and prefer to clone provider than make a partnership.

I respect their decision, but this puts me in an awkward position. Not only does it goes against the unification of InheritedWidgets, but it also prevents me from giving flutter_bloc as an official recommendation for peoples that wants to use provider.

That and the fact that I think their Flutter binding has a few flaws makes me want to make my own version of the Flutter binding (after asking them their permission).


To answer your other concerns here's what I currently have in mind for that package:


That's it for now!

Again, thanks a lot for the issue.

Please feel free to comment on that, nothing is set in stone yet. If you think this is a bad decision, I can change my plans if needed.

pavanpodila commented 5 years ago

I would have prefered to have everything under provider but I see that dependencies list will include bloc, mobx, scoped_model and potentially other frameworks. This is obviously does not make much sense.

I think having a per-framework package is a good middle-ground. It keeps the surface area lean and easier to maintain. My 2c.

warriorCoder commented 5 years ago

I wholeheartedly applaud your decision to not move forward with a provider_bloc library!! That said you did mention in your post that flutter bloc "has a few flaws", and I'm curious what flaws do you see that flutter_bloc has and what would be your suggestion for overcoming said flaws?

I still think, with the popularity of the provider package, that it would be a stellar idea for you to create a plugin that can be used with flutter_bloc that just has the DI components of provider. (Mind you with the new 0.18 version of flutter_bloc this isn't needed as much as the ImmutableProvider can handle the DI.) I see this a providing a unification of the packages and the true spirit of open source helping to make the software better by contributing back to the original package.

rrousselGit commented 5 years ago

I still think, with the popularity of the provider package, that it would be a stellar idea for you to create a plugin that can be used with flutter_bloc that just has the DI components of provider.

That's sadly not possible.

The only way to make a provider plugin is to recreate flutter_bloc entirely. The way flutter_bloc works is incompatible with provider and making flutter_bloc compatible would require too much work.


About the potential "flaws".

I could list some more, but these are the two "real" issues that can't be fixed without a rewrite of BlocProvider. Other potential issues could be solved, I already discussed some with the maintainers.

basketball-ico commented 5 years ago

@rrousselGit hello

There's no way to subscribe to the value of a BLoC without obtaining the BLoC itself. Which means that we can't make a BLoC read-only. Provider solves this kind of issues by having the provider do the listening instead of the consumer.

Why you need a BLoC read-only?

The current state of a BLoC can't be easily obtained inside other life-cycles of a widget (initState/didChangeDependencies). That requires an additional boilerplate that is error-prone (for example if we use Stream.listen manually, it's easy to forget to cancel the subscription).

BlocProvider use ancestorInheritedElementForWidgetOfExactType and currently you can easy obtain the current state in other life-cycles of a widget (initState/didChangeDependencies) like this

BlocProvider.of<MyBloc>(context).currentState;

thanks

rrousselGit commented 5 years ago

That's getting a bit off topic. I can answer to these remarks and point further concerns on gitter instead https://gitter.im/flutter_provider/community

But tl:dr I think it should be the provider that does the listening and pass the value through inheritFromWidgetOfExactType, instead of the consumer does the listening and using ancestorStateForWidgetOfExactType.

warriorCoder commented 5 years ago

I'd be interested in furthering these discussions but when I think about blocs as finite state machines I don't see the flaws you see and rather see the current flow being how the process works.

I can subscribe to the bloc in the initState method using BlocProvider.of so I'm not really sure about your second point.

Thanks again for being willing to discuss!! Your engagement is appreciated.

rrousselGit commented 5 years ago

Closing this since I won't go with the flutter_bloc binding for now

chimon2000 commented 5 years ago

The toxicity of the language used in this issue does not reflect the culture that Flutter promotes in its code of conduct. It's not just about making valid points - how they are made matters when we talk about preserving the community.