design patterns – How do I implement a domain entity behaviour that depends on some external infrastructure?

is it acceptable to inject the device API into the domain entity as follows

The DDD police are not going to come after you. Evans, in the blue book, documents a number of common patterns when implementing domain models, but that’s not a closed set: you are allowed to use other patterns if they are appropriate.

In his chapter on modeling a domain, Evans describes three common patterns: entities, value objects, and “stateless” domain services. It’s fairly common to have your domain entity talk to something on the “outside” via a domain service, and passing the domain service as an argument is the usual way to make that possible.

Starter, here, looks like a pretty reasonable domain service.

This isn’t the only possible answer. Domain models are largely about bookkeeping; they aren’t “do-ers”, they are “keep-track-of-ers”. Domain entities are how we write down what happens. The doing of things (including storing copies of the entities in our database) is often located in the application code.

In cases where that separation is important (in particular, in cases where you don’t want failure modes polluting your domain logic), it may make sense to do the work a level up, and then pass information to the domain entities to compute what to write down.

I recommend taking a look at Cory Benfield’s talk on building protocol libraries, which uses a similar pattern.

What would happen if the device starts successfully, but the start() command on the aggregate fails?

Failure modes in distributed systems are hard. What if the device starts, but the message announcing that the device started gets lost on the network? What if the entity computes what to write down, but the app crashes trying to write the data?

If you are trying to distribute two or more side effects, and you don’t have the guarantees about being able to commit/rollback both effects together, then you are pretty much guaranteed at least one failure mode where the system ends up in an inconsistent state.