I'm working on an application that loads untrusted assemblies via an interface. Each of those assemblies should be able to add one or more GameAction objects to a thread-safe queue used by the server.
The first iteration of design was to just pass the queue--something like this:
public interface IGameClient
{
void HandleStateChange(IGameState gameState,
ref Queue<IGameAction> actionQueue);
}
But, the problem with this is that it gives an untrusted assembly access to a shared queue, allowing it to manipulate other members of the queue and discover information about other queue actions.
The second pass was:
public interface IGameClient
{
void HandleStateChange(IGameState gameState);
GameActionDelegate event HasNewEvent; // passes IGameAction as a parameter
}
The problem with this is that it doesn't necessarily allow for the ordering or grouping of actions.
What I'm really hoping for is to be able to pass a reference to an object that encapsulates the thread-safe queue, but only exposes Enqueue(). But, I'm afraid that an untrusted assembly could manipulate a private Queue object using reflection.
So, what's the best way to handle this?