It depends on the requirements of your design. For example, do you want one unique/global "Activate" action, or do you want discrete activation actions for different types of objects? Is the "Activate" action for a light switch the same as the "Activate" action for a coffee maker, but with different behavior? Or are they completely different actions with identical names?
If you want to be able to bind actions to input gestures (e.g. keystrokes), then you'll probably want to go with the first option. In that case, you probably don't want the action to know every object on which it can be performed. You might not want a rigid set of actions supported by each object, either. Instead, your design could enable you to bind (or attach) action handlers to potential targets, delegating the behavior out to a callback. Action bindings could be bound to object types (metadata) or to actual object instances (or both).
Let's say I have a light switch, and I want it to support the Activate action. My code might look something like this:
lightSwitch.ActionBindings.Add(
new ActionBinding(
StandardActions.Activate,
delegate (object target)
{
var lightSwitch = (LightSwitch)target;
if (lightSwitch.IsDestroyed)
return false;
lightSwitch.IsActivated = !lightSwitch.IsActivated;
return true;
}));
This is simplified a bit, but the idea is that the behavior is injected via a callback, and the callback could return a value indicating success. In practice, you would probably want a second "can execute" callback in addition to the default "execute" callback.
Now, when the player hits the key bound to the "Activate" action, the target object should be queried to see if it has an ActionBinding for the "Activate" action. If so, the "can execute" callback should be checked (if one exists), and on successful evaluation, the "execute" callback should be invoked. If the action succeeds, stop. Otherwise, walk up the object tree until you find an object which will accept the action. That last step is only necessary if your objects are grouped in a hierarchy, i.e. the object is part of a larger composite object which might be the "true" action target.
Your callbacks could easily query the target object or game state as necessary. You might consider exposing services or state using a Service Locator pattern.