Provider: এটি কী, Flutter অ্যাপ স্টেট ম্যানেজার

লেখক: IT Sectr প্রকাশিত: 2026-02-19 পড়ার সময়: 7 মিনিট

Provider — Flutter-এর জন্য একটি স্টেট ম্যানেজমেন্ট প্যাকেজ, যা Remi Rousselet 2019 সালে InheritedWidget-এর উপর একটি র্যাপার হিসেবে তৈরি করেছেন। Provider props drilling ছাড়াই উইজেট ট্রিতে নিচের দিকে ডেটা পাঠানোর সমস্যা সমাধান করে: যেকোনো উইজেট context.read<T>() বা context.watch<T>()-এর মাধ্যমে স্টেট অ্যাক্সেস করতে পারে। pub.dev অনুযায়ী, প্রোভাইডার হল Flutter-এর সবচেয়ে জনপ্রিয় স্টেট ম্যানেজার যার ২৫ হাজারেরও বেশি লাইক রয়েছে।

মূল বিষয়

  • ChangeNotifier — পরিবর্তন সম্পর্কে সাবস্ক্রাইবারদের জানানোর জন্য notifyListeners সহ একটি ক্লাস
  • Consumer — একটি উইজেট যা ChangeNotifier পরিবর্তিত হলে পুনর্নির্মাণ করে
  • MultiProvider — নেস্টিং ছাড়াই একাধিক Provider-এর সংমিশ্রণ
  • ProxyProvider — একটি Provider যা অন্য Provider-এর উপর নির্ভর করে
  • context.read / context.watch — সাবস্ক্রিপশন ছাড়া এবং সহ স্টেট পড়ার পদ্ধতি

Provider কী?

Provider — Flutter-এ স্টেট ম্যানেজমেন্ট এবং ডিপেনডেন্সি ইনজেকশনের জন্য একটি প্যাকেজ, যা InheritedWidget-এর উপর নির্মিত। Provider উইজেট ট্রিতে একটি অবজেক্ট (স্টেট, সার্ভিস, রিপোজিটরি) সরবরাহ করে এবং ডেটা পরিবর্তিত হলে স্বয়ংক্রিয়ভাবে UI পুনর্নির্মাণ করে। InheritedWidget-এর সরাসরি ব্যবহারের বিপরীতে, Provider সমস্ত boilerplate সরিয়ে দেয়: InheritedWidget-এর সাবক্লাস লেখার, স্ট্যাটিক of() মেথড সেট আপ করার বা নেস্টিং পরিচালনার প্রয়োজন নেই।

Provider হল Google-এর দ্বারা Flutter-এ স্টেট ম্যানেজমেন্টের জন্য সরকারি ভাবে সুপারিশকৃত উপায় (Flutter Team, 2019-2023)। প্যাকেজটি Flutter Ecosystem-এর অংশ এবং Flutter টিম দ্বারা রক্ষণাবেক্ষণ করা হয়। এর লঞ্চের সময়, Provider গ্লোবাল ভেরিয়েবল এবং InheritedWidget-এর বিকল্প হিসাবে প্রস্তাবিত হয়েছিল: যেকোনো অবজেক্ট কনস্ট্রাক্টরের মাধ্যমে পাস না করেই যেকোনো জায়গা থেকে অ্যাক্সেসযোগ্য।

Flutter Community Survey 2025 অনুযায়ী, Provider 72% Flutter অ্যাপ্লিকেশনে ব্যবহৃত হয়। জনপ্রিয়তার প্রধান কারণ: ন্যূনতম প্রবেশের সীমা, অন্তর্নির্মিত ChangeNotifier সমর্থন, অন্যান্য আর্কিটেকচারের (MVVM, BLoC) সাথে সামঞ্জস্য এবং বাহ্যিক নির্ভরতার অনুপস্থিতি।

ChangeNotifier এবং notifyListeners

ChangeNotifier — Flutter-এর অন্তর্নির্মিত ক্লাস যা Listener প্যাটার্ন বাস্তবায়ন করে। ChangeNotifier notifyListeners() কল করে সাবস্ক্রাইবারদের পরিবর্তন সম্পর্কে জানায়। Provider-এর প্রসঙ্গে, ChangeNotifier হল স্টেটের জন্য প্রধান ক্লাস: ChangeNotifier-কে প্রসারিত করে এমন একটি ক্লাস ফিল্ড এবং মেথড সহ তৈরি করা হয় যা ডেটা পরিবর্তনের পরে notifyListeners() কল করে।

Dart
class CounterProvider extends ChangeNotifier {
  int _count = 0;
  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }

  void reset() {
    _count = 0;
    notifyListeners();
  }
}

notifyListeners-এর নিয়ম: ডেটা সম্পূর্ণ পরিবর্তন করার পরে কল করুন — মেথডের মাঝখানে নয়, শেষে। যদি একটি মেথড একাধিক পরিবর্তন করে, তবে প্রতিটি পরিবর্তনের পরে নয়, বরং সমস্ত পরিবর্তনের পরে একবার notifyListeners() কল করুন। এটি একটি লজিক্যাল ধাপে একাধিক পুনরায় অঙ্কন প্রতিরোধ করে। ব্যাচ আপডেটের জন্য, setState-এর মতো প্যাটার্নের সাথে notifyListeners ব্যবহার করুন।

ChangeNotifier-এর বিকল্প: ValueNotifier — একটি একক মানের জন্য (প্রিমিটিভের জন্য ভাল), StateNotifierstate_notifier প্যাকেজ থেকে (এককভাবে খুব কমই ব্যবহৃত হয়)। বেশিরভাগ Provider সমাধান এর অন্তর্নির্মিত সমর্থন এবং সরলতার কারণে ChangeNotifier ব্যবহার করে।

Consumer এবং context.watch

Consumer — একটি উইজেট যা ChangeNotifier-এ সাবস্ক্রাইব করে এবং প্রতিটি notifyListeners() কল এ পুনর্নির্মাণ করে। Consumer তিনটি প্যারামিটার সহ একটি builder ফাংশন নেয়: context, model, child। Child — একটি উইজেট যা মডেলের উপর নির্ভর করে না এবং Consumer দ্বারা পুনর্নির্মিত হয় না। এটি একটি অপ্টিমাইজেশন: যদি Consumer-এ একটি স্ট্যাটিক উইজেট (আইকন, ডেটা ছাড়া টেক্সট) থাকে, তবে এটি child-এর মাধ্যমে পাস করা হয় এবং পুনরায় তৈরি করা হয় না।

Dart
Consumer<CounterProvider>(
  builder: (context, provider, child) => Column(
    children: [
      child!, // পুনর্নির্মিত হয় না
      Text('${provider.count}'),
      ElevatedButton(
        onPressed: () => provider.increment(),
        child: Icon(Icons.add),
      ),
    ],
  ),
  child: Text('কাউন্টার:'),
)

context.watch — Provider-এ সাবস্ক্রাইব করার জন্য BuildContext-এর একটি এক্সটেনশন মেথড। মডেল ফেরত দেয় এবং বর্তমান উইজেটটিকে এর পরিবর্তনগুলিতে সাবস্ক্রাইব করে। context.read — সাবস্ক্রিপশন ছাড়া অ্যাক্সেস (onPressed হ্যান্ডলার, initState এবং dispose-এর জন্য)। context.select — অন্যান্য ফিল্ড পরিবর্তিত হলে পুনর্নির্মাণ ছাড়াই মডেলের একটি নির্দিষ্ট ফিল্ডে সাবস্ক্রিপশন। Select হল জটিল মডেলের জন্য সবচেয়ে কার্যকরী বিকল্প যেখানে ১০+ ফিল্ড রয়েছে।

কখন Consumer, watch বা select ব্যবহার করবেন: Consumer — যখন অপ্টিমাইজেশনের জন্য child উইজেট প্রয়োজন। watch — সাধারণ পড়ার জন্য build মেথডে। select — যখন মডেলের একাধিক ফিল্ড থাকে কিন্তু উইজেট শুধুমাত্র একটির উপর নির্ভর করে। Provider উইজেট ধ্বংস হলে স্বয়ংক্রিয়ভাবে সাবস্ক্রিপশন বাতিল করে, মেমরি লিক প্রতিরোধ করে।

MultiProvider এবং ProxyProvider

MultiProvider — নেস্টিং ছাড়াই একাধিক Provider নিবন্ধনের জন্য একটি উইজেট। ৫ স্তরের Provider → Provider → Provider ট্রির পরিবর্তে, MultiProvider প্রদানকারীদের একটি তালিকা নেয়। প্রতিটি পরবর্তী Provider কনস্ট্রাক্টরের মাধ্যমে আগেরটি ব্যবহার করতে পারে। MultiProvider একটি অ্যাপ্লিকেশনের মূল স্তর সংগঠিত করার মানক উপায়।

Dart
MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (_) => CartProvider()),
    ChangeNotifierProvider(create: (_) => AuthProvider()),
    ProxyProvider<AuthProvider, OrderProvider>(
      update: (_, auth, __) => OrderProvider(auth.userId),
    ),
  ],
  child: MaterialApp(home: HomePage()),
)

ProxyProvider — একটি Provider যা অন্য Provider-এর উপর নির্ভর করে। ProxyProvider অন্যান্য Provider থেকে মান নেয় এবং সেগুলি তার অবজেক্টে পাঠায়। উদাহরণস্বরূপ, OrderProvider AuthProvider-এর উপর নির্ভর করে (userId প্রয়োজন)। যখন AuthProvider পরিবর্তিত হয়, ProxyProvider স্বয়ংক্রিয়ভাবে নতুন userId দিয়ে OrderProvider পুনরায় তৈরি করে। ChangeNotifierProxyProvider — ChangeNotifier-এর জন্য ProxyProvider-এর সংস্করণ।

StreamProvider এবং FutureProvider: StreamProvider একটি Stream (Firebase, WebSocket)-এ সাবস্ক্রাইব করে এবং প্রতিটি নতুন ইভেন্টে Consumer আপডেট করে। FutureProvider — অ্যাসিঙ্ক্রোনাস আরম্ভের জন্য: একটি Future চালায়, লোডিং দেখায়, তারপর ফলাফল উইজেটে পাঠায়। উভয়ই ম্যানুয়াল সাবস্ক্রিপশন পরিচালনা ছাড়াই সাধারণ কাজগুলি সমাধান করে।

Provider পরীক্ষা করা

Provider পরীক্ষা করা হয় উইজেটকে পরীক্ষার মান সহ MultiProvider-এ মোড়ানোর মাধ্যমে। পরীক্ষার জন্য প্রকৃত API বা ডাটাবেসের প্রয়োজন নেই — Provider একটি মক করা অবজেক্ট দিয়ে প্রতিস্থাপিত হয়। provider প্যাকেজ পরীক্ষা বিচ্ছিন্নতার জন্য ProviderScope সরবরাহ করে — প্রতিটি পরীক্ষা স্বাধীনভাবে তার নিজস্ব Provider ট্রি তৈরি করে।

Dart
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('Counter increments on button tap',
    (tester) async {
      await tester.pumpWidget(
        ChangeNotifierProvider(
          create: (_) => CounterProvider(),
          child: CounterScreen(),
        ),
      );
      await tester.tap(find.byKey(Key('increment')));
      await tester.pump();
      expect(find.text('১'), findsOneWidget);
    },
  );
}

MockProvider: API-এর উপর নির্ভরশীল Provider সহ উইজেট পরীক্ষার জন্য, একটি স্টাব সাবক্লাস তৈরি করুন বা mockito / mocktail ব্যবহার করুন। Provider-এর বিশেষ মক টুলের প্রয়োজন নেই — ChangeNotifier-কে প্রসারিত করে এমন যেকোনো অবজেক্ট প্রকৃত সার্ভিস কল না করেই create-এর মাধ্যমে পাস করা যেতে পারে। সহজ প্রতিস্থাপনের জন্য ইন্টারফেস (অ্যাবস্ট্রাক্ট ক্লাস) এর মাধ্যমে Provider প্রোগ্রাম করুন।

Provider: কর্মক্ষমতা এবং সীমাবদ্ধতা

Provider-এর কর্মক্ষমতা InheritedWidget-এর উপর ভিত্তি করে: যখন একটি Provider পরিবর্তিত হয়, context.watch বা Consumer-এর মাধ্যমে সাবস্ক্রাইব করা সমস্ত উইজেট পুনর্নির্মিত হয়। অপ্রয়োজনীয় পুনরায় অঙ্কন প্রতিরোধ করতে, context.select (একটি নির্দিষ্ট ফিল্ডে সাবস্ক্রিপশন), Consumer child প্যারামিটার সহ এবং স্ট্যাটিক উইজেটের জন্য const ব্যবহার করুন। Provider পরিবর্তনে সাবস্ক্রাইব না করা শাখাগুলি পুনর্নির্মাণ করে না।

পদ্ধতিসাবস্ক্রিপশনপুনর্নির্মাণব্যবহার
context.watchসম্পূর্ণ মডেলযেকোনো পরিবর্তনসাধারণ উইজেট
Consumerসম্পূর্ণ মডেলযেকোনো পরিবর্তনchild অপ্টিমাইজেশন সহ
context.selectনির্দিষ্ট ফিল্ডশুধুমাত্র ফিল্ড পরিবর্তিত হলেজটিল মডেল
context.readনাকখনই নয়ইভেন্ট হ্যান্ডলার

সীমাবদ্ধতা: Provider ইভেন্ট স্তরে ব্যবসায়িক লজিক বিচ্ছিন্নতা (BLoC-এর মতো) সমর্থন করে না। সমস্ত পরিবর্তন ChangeNotifier মেথডের সরাসরি কলের মাধ্যমে ঘটে, যা অনিয়ন্ত্রিত পরিবর্তন শৃঙ্খলের দিকে নিয়ে যেতে পারে। জটিল দৃশ্যপটের জন্য (একাধিক অ্যাসিঙ্ক্রোনাস অপারেশন, জটিল বৈধতা), Provider BLoC এবং Riverpod-এর তুলনায় পিছিয়ে থাকে।

Provider থেকে মাইগ্রেশন: Provider সহজেই অন্যান্য প্যাকেজের সাথে একত্রিত করা যায়। Riverpod-এ মাইগ্রেট করতে, ChangeNotifierProvider.adaptive ব্যবহার করুন — একটি অ্যাডাপ্টার যা পুনর্লিখন ছাড়াই বিদ্যমান ChangeNotifier-কে Riverpod-এর সাথে ব্যবহার করতে দেয়। BLoC-এর জন্য — BlocProvider-কে Provider ট্রির ভিতরে রাখা যেতে পারে, ধীরে ধীরে ChangeNotifier-কে Bloc দিয়ে প্রতিস্থাপন করে।

সচরাচর জিজ্ঞাসিত প্রশ্ন

Provider BLoC থেকে কীভাবে আলাদা?

Provider — ChangeNotifier সহ ডিপেনডেন্সি ইনজেকশনের জন্য InheritedWidget-এর উপর একটি র্যাপার। BLoC — লজিক বিচ্ছিন্নতার জন্য Event + Stream সহ একটি আর্কিটেকচারাল প্যাটার্ন। Provider শেখা সহজ, BLoC কোডকে আরও কঠোরভাবে গঠন করে। Provider ছোট অ্যাপ্লিকেশন এবং UI স্টেটের জন্য উপযুক্ত, BLoC জটিল ব্যবসায়িক লজিকের জন্য। Flutter Community 2025 অনুযায়ী, উভয়ই প্রায়শই একই প্রকল্পে একসাথে ব্যবহৃত হয়।

ChangeNotifierProvider কী?

ChangeNotifierProvider — ChangeNotifier ইনস্ট্যান্সের জন্য Provider-এর একটি প্রকার। create-এর মাধ্যমে অবজেক্ট তৈরি করে, বংশধরদের সরবরাহ করে এবং notifyListeners কল করা হলে Consumer পুনর্নির্মাণ করে। ChangeNotifierProvider ট্রি থেকে সরানো হলে ChangeNotifier-এ স্বয়ংক্রিয়ভাবে dispose কল করে। তিনটি তৈরি পদ্ধতি আছে: ChangeNotifierProvider.value (বিদ্যমান অবজেক্টের জন্য), ChangeNotifierProvider (lazy তৈরি করার জন্য) এবং ChangeNotifierProvider.create (স্পষ্ট lazy তৈরি করার জন্য)।

Provider-এর সাথে অপ্রয়োজনীয় পুনর্নির্মাণ কীভাবে এড়াবেন?

context.watch-এর পরিবর্তে context.select ব্যবহার করুন — উইজেট শুধুমাত্র নির্বাচিত ফিল্ড পরিবর্তিত হলে পুনর্নির্মাণ করে। বড় ChangeNotifier-কে কয়েকটি ছোটে ভাগ করুন (এক মডেল — এক দায়িত্ব)। স্ট্যাটিক অংশের জন্য Consumer child ব্যবহার করুন। তালিকার জন্য, কী সহ ListView.builder ব্যবহার করুন। Provider DevTools (Flutter Inspector) দেখায় কোন উইজেট পুনর্নির্মাণ করছে এবং কেন।

ChangeNotifier ছাড়া Provider ব্যবহার করা যায়?

হ্যাঁ। Provider (ChangeNotifier ছাড়া) — অপরিবর্তনীয় অবজেক্ট (রিপোজিটরি, API ক্লায়েন্ট, কনফিগারেশন) ইনজেক্ট করার জন্য। ValueListenableProvider — ValueNotifier-এর জন্য। StreamProvider — Stream (Firebase, WebSocket)-এর জন্য। FutureProvider — Future (স্টার্টআপে কনফিগারেশন লোড করা)-এর জন্য। ProxyProvider — সেই Provider-গুলির জন্য যা অন্য Provider-এর উপর নির্ভর করে। ChangeNotifier শুধুমাত্র UI আপডেট সহ পরিবর্তনযোগ্য স্টেটের জন্য প্রয়োজন।

ProviderNotFoundException কী?

ProviderNotFoundException — একটি রানটাইম ব্যতিক্রম যা ঘটে যখন একটি Provider পাওয়ার চেষ্টা করা হয় যা উইজেট ট্রিতে উপরে ঘোষণা করা হয়নি। সাধারণ কারণ: Provider উইজেটের নীচে ঘোষণা করা হয়েছে যা এটি পড়ার চেষ্টা করছে; Provider একটি রুটে ঘোষণা করা হয়েছে এবং অন্যটিতে পড়া হচ্ছে; টাইপে টাইপো ত্রুটি। সমাধান: Provider-কে ট্রিতে উপরে সরান বা বৈশ্বিক নির্ভরতার জন্য MaterialApp স্তরে MultiProvider ব্যবহার করুন।

সারসংক্ষেপ

  • Provider — Flutter-এ স্টেট ম্যানেজমেন্ট এবং DI-এর জন্য InheritedWidget-এর উপর একটি র্যাপার
  • ChangeNotifier — প্রতিক্রিয়াশীল UI আপডেটের জন্য notifyListeners সহ একটি ক্লাস
  • Consumer এবং context.watch — স্বয়ংক্রিয় পুনর্নির্মাণ সহ পরিবর্তনের সাবস্ক্রিপশন
  • MultiProvider — ট্রি নেস্টিং ছাড়াই প্রদানকারীদের সংমিশ্রণ
  • ProxyProvider — Provider-এর মধ্যে নির্ভরতা শৃঙ্খল
  • context.select — মডেলের একটি নির্দিষ্ট ফিল্ডে লক্ষ্যবস্তু সাবস্ক্রিপশন
  • StreamProvider এবং FutureProvider — প্রতিক্রিয়াশীল এবং অ্যাসিঙ্ক্রোনাস ডেটার জন্য অন্তর্নির্মিত সমর্থন

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন