Can I apply adjustments (discounts) through a controller?
Generally speaking, no. Adjusters should always be computed from the current state of the order—the information required to match an Adjuster should be attached directly to an order.
Your custom Adjuster is registered globally, then applied to Orders that match criteria you've defined in its adjust() method. That method returns an array of Adjustment models, which are then attached to the order.
In this case, what I'd recommend doing is something like this, in your controller:

Looks up the Entry based on a URL param (?code=abc);
Load the current user's Cart;
Set that Entry on the Order via a custom Entry field: $order-&gt;setFieldValue('myDiscountEntryField', [$discountEntry]); (noting that the value is an array, due to the way Relational data is saved!)
Save the Cart/Order: Craft::$app-&gt;getElements()-&gt;saveElement($order);

At this point, Commerce automatically offers each registered Adjuster an opportunity to apply adjustments to the Order.
In your Adjuster, use the attached Discount Entry data to return an Adjustment:
class MyAdjuster implements AdjusterInterface
{
  public function adjust(craft\commerce\elements\Order $order): array
  {
    $discountEntry = $order-&gt;myDiscountEntryField-&gt;one();

    // We don't want to assume every order contains valid data, and if we can bail early, let's take the opportunity:
    if (!$discountEntry) {
      // The method signature still requires an array returned, but in this case and empty array is basically saying &quot;no adjustments applied.&quot;
      return [];
    }

    // Then here, you'll create and return your Adjustment models (like you have in the original question)!
    $adjustments = [];


    // ... Loop over your items...
    foreach ($order-&gt;getLineItems() as $lineItem) {
      // ...and use `$adjustments[] = $adjustment` to push new ones into the array, or just `continue;` if you want to skip one.
    }

    // Return anything that was added:
    return $adjustments;
  }
}


If you apply Adjustments outside of this process (the automatic recalculation step, which happens when saving a Cart), you are not likely to have a consistent experience, because they won't be injected the next time a Cart is saved!