<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alireza Easazade</title>
    <description>The latest articles on DEV Community by Alireza Easazade (@easazade).</description>
    <link>https://dev.to/easazade</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F280741%2Fbb7df25a-f1f4-473f-b43a-68d7bd0d66c7.jpg</url>
      <title>DEV Community: Alireza Easazade</title>
      <link>https://dev.to/easazade</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/easazade"/>
    <language>en</language>
    <item>
      <title>Weaver: Flutter Dependency Injection Without the Mental Overhead</title>
      <dc:creator>Alireza Easazade</dc:creator>
      <pubDate>Thu, 01 Jan 2026 12:50:13 +0000</pubDate>
      <link>https://dev.to/easazade/weaver-flutter-dependency-injection-without-the-mental-overhead-94j</link>
      <guid>https://dev.to/easazade/weaver-flutter-dependency-injection-without-the-mental-overhead-94j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Describe your intent. Let Weaver handle the rest.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  👀 Overview
&lt;/h2&gt;

&lt;p&gt;Weaver is a dependency injection library for Flutter and Dart designed to reduce one thing above all else: &lt;strong&gt;mental overhead&lt;/strong&gt;. It stays out of your way, removes hidden rules, and lets you focus on building features instead of managing wiring.&lt;/p&gt;

&lt;p&gt;It does not rely on the widget tree or &lt;code&gt;BuildContext&lt;/code&gt;, and it frees you from timing issues where dependencies may or may not be ready when accessed. There are no fragile placement requirements, no guessing games, and no race conditions to think about.&lt;/p&gt;

&lt;p&gt;By fully decoupling dependency registration, injection, and scope management, Weaver introduces a calmer and more predictable mental model for DI in Flutter. You describe what exists, when it exists, and where you need it. Weaver takes care of the rest — quietly and predictably.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Why dependency injection feels harder than it should
&lt;/h2&gt;

&lt;p&gt;If you have used dependency injection in Flutter long enough, this probably feels familiar.&lt;/p&gt;

&lt;p&gt;At first, things seem simple. You add a &lt;code&gt;Provider&lt;/code&gt;, a &lt;code&gt;BlocProvider&lt;/code&gt;, or a use a library like &lt;code&gt;get_it&lt;/code&gt;, and everything works. But as the app grows, dependency injection slowly turns into something you &lt;em&gt;manage&lt;/em&gt; rather than something that just works.&lt;/p&gt;

&lt;p&gt;You start moving providers higher in the widget tree "just in case." You wrap entire subtrees to avoid &lt;code&gt;ProviderNotFoundException&lt;/code&gt;. You worry about whether a dependency is created before a widget builds. You delay logic, add loading states, or restructure code simply to make DI behave.&lt;/p&gt;

&lt;p&gt;None of this feels like business logic, yet it takes a surprising amount of mental energy.&lt;/p&gt;

&lt;p&gt;The problem is not Flutter, and it is not that libraries like Provider or get_it are bad. The problem is that several responsibilities are tightly coupled together or sometimes the solutions are just not there:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;where&lt;/em&gt; a dependency is provided&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;when&lt;/em&gt; it is created&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;how long&lt;/em&gt; it should live&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;who&lt;/em&gt; is allowed to access it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When these concerns leak into your UI and application logic, dependency injection stops being a tool and starts becoming a constant background concern.&lt;/p&gt;

&lt;p&gt;Weaver was designed by starting from this question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if dependency injection required almost no thinking at all?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What if you could describe intent instead of wiring, lifecycles instead of placement, and let the system handle the rest?&lt;/p&gt;

&lt;h2&gt;
  
  
  🧭 A belief that shaped Weaver
&lt;/h2&gt;

&lt;p&gt;There is a belief I have carried for years while building software.&lt;/p&gt;

&lt;p&gt;If a solution is truly good, it should handle &lt;strong&gt;all valid cases of the problem&lt;/strong&gt;, not just the most common ones.&lt;/p&gt;

&lt;p&gt;I once worked with a CTO who told me something I never fully accepted: that when it comes to problems like state management, there is no solution that fits all cases. That every application is different, and every solution inevitably breaks down somewhere.&lt;/p&gt;

&lt;p&gt;I refused to accept that.&lt;/p&gt;

&lt;p&gt;Not because problems are simple, but because many of them are &lt;em&gt;poorly defined&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When you reduce a problem to its essence, understand its true boundaries, and describe it precisely, patterns emerge. At that point, a general solution becomes possible.&lt;/p&gt;

&lt;p&gt;This mindset heavily influenced how Weaver was designed. Instead of reacting to individual edge cases, it starts by asking a simpler question: what is dependency injection &lt;em&gt;really&lt;/em&gt; about?&lt;/p&gt;

&lt;p&gt;Defining the problem correctly is often more important than writing the solution. In programming, I have found this to be a recurring truth. One sentence I often repeat is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One developer’s solution is another developer’s problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What works cleanly for one developer may create friction for another, simply because perspectives differ.&lt;/p&gt;

&lt;p&gt;Weaver aims to avoid becoming that problem by simplifying dependency injection down to its core ideas and handling the complexity centrally, rather than spreading it across your codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ Key Benefits
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Context-free dependency access
&lt;/h3&gt;

&lt;p&gt;Weaver completely removes dependency injection from the widget tree. There is no &lt;code&gt;BuildContext&lt;/code&gt;, no inherited widgets, and no fragile placement rules. Dependencies can be registered and retrieved from anywhere in your codebase, making architectural boundaries clearer and reducing accidental coupling between UI and application logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. No race conditions, ever
&lt;/h3&gt;

&lt;p&gt;With APIs like &lt;code&gt;getAsync()&lt;/code&gt; and widgets such as &lt;code&gt;RequireDependencies&lt;/code&gt;, Weaver eliminates an entire class of timing bugs. You can safely request dependencies before they are registered, and Weaver will resolve them as soon as they become available. This removes common issues like &lt;code&gt;ProviderNotFoundException&lt;/code&gt; and awkward initialization ordering.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Safe and predictable widget building
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;RequireDependencies&lt;/code&gt; allows widgets to declare what they need and build only when those dependencies are ready. Widgets become declarative about their requirements instead of defensive about missing state. This leads to simpler build methods and a much more relaxed mental model when composing UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. True separation of responsibilities
&lt;/h3&gt;

&lt;p&gt;Weaver intentionally decouples three concerns that are often tangled together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;registering dependencies&lt;/li&gt;
&lt;li&gt;injecting dependencies&lt;/li&gt;
&lt;li&gt;managing lifecycles and scopes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each concern has a clear, focused API. This separation makes large applications easier to reason about, easier to refactor, and safer to evolve over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. First-class scoped dependencies
&lt;/h3&gt;

&lt;p&gt;Weaver treats scopes as a core concept rather than an afterthought. Dependencies can live globally or only within well-defined lifecycles such as authentication, admin mode, or feature-specific flows. Entering and leaving scopes is explicit, observable, and deterministic, which maps naturally to real business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Lazy by default, efficient by design
&lt;/h3&gt;

&lt;p&gt;Dependencies can be registered lazily and instantiated only when actually needed. Combined with scopes, this avoids unnecessary object creation and keeps memory usage under control without adding complexity for the developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Clear handling of multiple instances
&lt;/h3&gt;

&lt;p&gt;Named dependencies make it straightforward to work with multiple instances of the same type. Code generation turns these named registrations into expressive, type-safe getters, improving readability and eliminating stringly-typed lookups throughout the codebase.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Built for testing and observability
&lt;/h3&gt;

&lt;p&gt;Weaver makes testing easier by supporting reassignment of dependencies and full resets of the container state. Observers allow you to react to registrations and unregistrations, making application state changes visible and debuggable instead of implicit and hidden.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. A calmer mental model for Flutter DI
&lt;/h3&gt;

&lt;p&gt;Perhaps the biggest benefit is intangible: Weaver reduces cognitive load. There is no need to remember where providers are placed, when objects are created, or which part of the tree owns what. You describe what exists, when it exists &amp;amp; where you need it and Weaver takes care of the rest.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 Installation
&lt;/h2&gt;

&lt;p&gt;Before diving into examples, add Weaver to your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;weaver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^x.y.z&lt;/span&gt; &lt;span class="c1"&gt;# for Dart-only projects&lt;/span&gt;
  &lt;span class="na"&gt;flutter_weaver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^x.y.z&lt;/span&gt; &lt;span class="c1"&gt;# for Flutter projects&lt;/span&gt;

&lt;span class="na"&gt;dev_dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build_runner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;weaver_builder&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^x.y.z&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once added, you can start describing dependencies and scopes without worrying about wiring.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔄 From wiring dependencies to describing intent
&lt;/h2&gt;

&lt;p&gt;Most dependency injection setups start by asking &lt;em&gt;how&lt;/em&gt; things should be wired.&lt;/p&gt;

&lt;p&gt;Where should this provider live? Which widget owns it? Do I create it eagerly or lazily? What happens if another widget needs it earlier than expected?&lt;/p&gt;

&lt;p&gt;These are implementation questions, but they tend to leak everywhere.&lt;/p&gt;

&lt;p&gt;Weaver flips this around. Instead of thinking about wiring, you describe &lt;strong&gt;intent&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what dependency exists&lt;/li&gt;
&lt;li&gt;when it should exist&lt;/li&gt;
&lt;li&gt;and where it is needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything else becomes an implementation detail handled by the system.&lt;/p&gt;

&lt;p&gt;To see the difference, let’s look at a simple, familiar example.&lt;/p&gt;

&lt;h3&gt;
  
  
  A common setup with Provider
&lt;/h3&gt;

&lt;p&gt;Imagine a simple &lt;code&gt;UserBloc&lt;/code&gt; that depends on a &lt;code&gt;UserRepository&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With a widget-tree-based approach, you might end up with something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;MultiProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nl"&gt;providers:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;create:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserBloc&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;create:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;UserBloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;repository:&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works, but notice what you are now responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ordering providers correctly&lt;/li&gt;
&lt;li&gt;making sure nothing accesses &lt;code&gt;UserBloc&lt;/code&gt; too early&lt;/li&gt;
&lt;li&gt;placing this high enough in the widget tree&lt;/li&gt;
&lt;li&gt;refactoring widget structure carefully to avoid breakage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code is not wrong. It is just &lt;em&gt;mentally noisy&lt;/em&gt; as applications grow.&lt;/p&gt;

&lt;h3&gt;
  
  
  The same intent with Weaver
&lt;/h3&gt;

&lt;p&gt;With Weaver, the same setup becomes a description of intent rather than wiring:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;UserBloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;useRepository:&lt;/span&gt; &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And wherever you need &lt;code&gt;UserBloc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;userBloc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserBloc&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no widget placement to think about, no ordering anxiety, and no concern about timing. If the dependency exists, you get it. If it does not yet exist, Weaver resolves it when it becomes available.&lt;/p&gt;

&lt;p&gt;The code is shorter, calmer, and focused on &lt;em&gt;what&lt;/em&gt; the app needs, not &lt;em&gt;how&lt;/em&gt; it is wired.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧩 Building widgets with &lt;code&gt;RequireDependencies&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A common source of DI pain in Flutter is that widgets often need dependencies that are not guaranteed to exist yet.&lt;/p&gt;

&lt;p&gt;Maybe a bloc is registered later during startup. Maybe it is created only after a user authenticates. Maybe it lives inside a scope that you enter and leave based on business logic.&lt;/p&gt;

&lt;p&gt;In widget-tree DI, this typically turns into placement anxiety and defensive code: you move providers around, add guards, and hope you never hit &lt;code&gt;ProviderNotFoundException&lt;/code&gt; in the wrong navigation path.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;RequireDependencies&lt;/code&gt; is Weaver’s way of making this problem disappear.&lt;/p&gt;

&lt;p&gt;You simply declare what the widget requires. Weaver will rebuild when those dependencies become available, and you get a single &lt;code&gt;isReady&lt;/code&gt; flag to drive the UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: a profile page that requires authentication
&lt;/h3&gt;

&lt;p&gt;Imagine &lt;code&gt;ProfilePage&lt;/code&gt; needs a &lt;code&gt;UserBloc&lt;/code&gt;, but &lt;code&gt;UserBloc&lt;/code&gt; is registered only after the app enters an authentication scope.&lt;/p&gt;

&lt;p&gt;With Weaver, the widget does not need to know where &lt;code&gt;UserBloc&lt;/code&gt; comes from, when it is registered, or whether the scope is currently active. It only declares the requirement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProfileGate&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ProfileGate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;RequireDependencies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;weaver:&lt;/span&gt; &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;dependencies:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;DependencyKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;type:&lt;/span&gt; &lt;span class="n"&gt;UserBloc&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;isReady&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;isReady&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;CircularProgressIndicator&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// At this point, UserBloc is guaranteed to be available.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ProfilePage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part is not the loading spinner. The important part is the mental model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you do not wire providers into the widget tree&lt;/li&gt;
&lt;li&gt;you do not guess whether registration has already happened&lt;/li&gt;
&lt;li&gt;you do not care whether the dependency is global or scoped&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You just declare what is required. When it becomes ready, your widget builds.&lt;/p&gt;

&lt;p&gt;This is how Weaver keeps dependency injection out of your way, without adding new rules to remember.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⏳ Imperative waits with &lt;code&gt;getAsync()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Sometimes you are not inside the widget tree. You are in startup code, in a service, in a background task, or in an event handler where you want to write imperative code.&lt;/p&gt;

&lt;p&gt;That is where &lt;code&gt;weaver.getAsync()&lt;/code&gt; shines.&lt;/p&gt;

&lt;p&gt;It works like &lt;code&gt;weaver.get()&lt;/code&gt;, except it returns a &lt;code&gt;Future&lt;/code&gt; and waits until the dependency becomes available. You can call it &lt;em&gt;before&lt;/em&gt; the dependency is registered, and it will resolve the moment registration happens.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: handling a notification click
&lt;/h3&gt;

&lt;p&gt;A very common real-world case is handling a notification tap when the app is launched from the background or a terminated state.&lt;/p&gt;

&lt;p&gt;At that moment, the app may not have finished bootstrapping yet, and many dependencies may not be registered. Still, you want to react to the notification reliably.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;handleNotificationClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NotificationPayload&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Ask for the dependency immediately.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;userBlocFuture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserBloc&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// App startup continues elsewhere. At some point, after auth or setup,&lt;/span&gt;
  &lt;span class="c1"&gt;// the dependency is registered.&lt;/span&gt;
  &lt;span class="c1"&gt;// This might happen seconds later.&lt;/span&gt;

  &lt;span class="c1"&gt;// weaver.register(UserBloc());&lt;/span&gt;

  &lt;span class="c1"&gt;// Wait until UserBloc becomes available.&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;userBloc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;userBlocFuture&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Now it is safe to handle the notification.&lt;/span&gt;
  &lt;span class="n"&gt;userBloc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openFromNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  When to use which
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;RequireDependencies&lt;/code&gt; when building widgets.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;getAsync()&lt;/code&gt; when you are writing imperative code outside the UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎯 Scoped dependency management
&lt;/h2&gt;

&lt;p&gt;Many dependencies should not live for the entire lifetime of your app.&lt;/p&gt;

&lt;p&gt;Some only make sense in a specific context: when a user is authenticated, when an admin panel is active, or when a particular feature flow is entered.&lt;/p&gt;

&lt;p&gt;Weaver treats scopes as a first-class concept. When defining a scope, you only need to care about three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which dependencies should exist in that scope&lt;/li&gt;
&lt;li&gt;what should happen when the scope is entered&lt;/li&gt;
&lt;li&gt;what should happen when the scope is left&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything else is handled for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining a scope
&lt;/h3&gt;

&lt;p&gt;You define a scope by annotating a class. Inside it, you register dependencies that should live for the duration of that scope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@WeaverScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'auth'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_AuthScope&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@OnEnterScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;onEnter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Weaver&lt;/span&gt; &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserBloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;userId:&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@OnLeaveScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;onLeave&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Weaver&lt;/span&gt; &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unregister&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserBloc&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running code generation, Weaver creates everything needed to manage this scope.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entering and leaving a scope
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addScopeHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthScopeHandler&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// Enter the scope&lt;/span&gt;
&lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enterScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;userId:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Leave the scope&lt;/span&gt;
&lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;leaveScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthScope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scopeName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  A real-world example: reacting to authentication state
&lt;/h3&gt;

&lt;p&gt;In real applications, scopes are usually driven by business state rather than manual calls.&lt;/p&gt;

&lt;p&gt;A common pattern is reacting to an authentication bloc or cubit and entering or leaving scopes automatically based on the user’s status.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AuthBloc&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isAuthenticated&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authScope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isIn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// User just authenticated → enter auth scope&lt;/span&gt;
    &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enterScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;userId:&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isAuthenticated&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authScope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isIn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// User logged out → leave auth scope&lt;/span&gt;
    &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;leaveScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthScope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scopeName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the scope is entered, its dependencies become available. When the scope is left, they are removed automatically.&lt;/p&gt;

&lt;p&gt;The important part is that usage stays completely decoupled.&lt;/p&gt;

&lt;p&gt;When you use &lt;code&gt;UserBloc&lt;/code&gt;, you do not need to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;when the scope was entered&lt;/li&gt;
&lt;li&gt;where the dependency was registered&lt;/li&gt;
&lt;li&gt;how its lifecycle is managed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the scope is active, the dependency exists. If it is not, it does not.&lt;/p&gt;

&lt;p&gt;That is the power of Weaver’s scope management: explicit lifecycles without hidden complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏷️ Named dependencies and generated accessors
&lt;/h2&gt;

&lt;p&gt;Sometimes you need more than one instance of the same type for different purposes. Instead of creating wrapper classes or relying on comments and conventions, Weaver lets you &lt;strong&gt;name&lt;/strong&gt; dependencies explicitly.&lt;/p&gt;

&lt;p&gt;At the simplest level, you can register a named dependency by providing a name when registering:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;'token-value'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'auth-token'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;'user-id-123'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'user-id'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And retrieve them by name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'auth-token'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'user-id'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This already removes ambiguity, but Weaver goes one step further.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code-generated accessors for named dependencies
&lt;/h3&gt;

&lt;p&gt;Weaver can generate &lt;strong&gt;type-safe, intention-revealing accessors&lt;/strong&gt; for named dependencies. Instead of passing strings around, you declare named dependencies using annotations, and Weaver generates direct getters for you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@NamedDependency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'user-profile'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Profile&lt;/span&gt; &lt;span class="nf"&gt;_userProfile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Profile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@NamedDependency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'admin-profile'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Profile&lt;/span&gt; &lt;span class="nf"&gt;_adminProfile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Profile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running code generation, these become available as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;named&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;userProfile&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;adminProfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;named&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;adminProfile&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is clearer code, fewer mistakes, and a much stronger signal of intent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Named dependencies inside scopes
&lt;/h3&gt;

&lt;p&gt;The same idea applies to scopes. You can define named dependencies inside a scope, and Weaver will generate scoped accessors for them as well.&lt;/p&gt;

&lt;p&gt;For example, if a scope defines a named dependency called &lt;code&gt;userId&lt;/code&gt;, it can be accessed like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weaver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authScope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You do not need to manage registration or cleanup manually. When the scope is active, the accessor is valid. When the scope is left, the dependency is gone.&lt;/p&gt;

&lt;p&gt;This keeps even advanced use cases consistent with the same calm mental model Weaver applies everywhere else.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌿 Closing thoughts
&lt;/h2&gt;

&lt;p&gt;Dependency injection should not be something you constantly think about. It should not shape how you structure your widgets, force you to worry about timing, or leak lifecycle concerns into places where they do not belong.&lt;/p&gt;

&lt;p&gt;Weaver was built around a simple goal: &lt;strong&gt;reduce mental overhead&lt;/strong&gt;. By separating responsibilities, making scopes explicit, and letting you declare intent instead of wiring, it allows dependency injection to fade into the background where it belongs.&lt;/p&gt;

&lt;p&gt;When DI stays out of your way, you spend less time managing infrastructure and more time building features that actually matter.&lt;/p&gt;

&lt;p&gt;If this mental model resonates with you, you can explore the full documentation, examples, and API reference here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pub.dev/packages/weaver" rel="noopener noreferrer"&gt;👉 https://pub.dev/packages/weaver&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Weaver is opinionated by design, but that opinion is simple: dependency injection should feel calm, predictable, and almost invisible.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>di</category>
      <category>dependencyinjection</category>
    </item>
  </channel>
</rss>
