我正在开发一个通过接口加载不受信任的程序集的应用程序。每个程序集都应该能够将一个或多个GameAction对象添加到服务器使用的线程安全队列中。
设计的第一次迭代就是通过队列 - 类似这样:
public interface IGameClient
{
void HandleStateChange(IGameState gameState,
ref Queue<IGameAction> actionQueue);
}
但是,问题在于它给不受信任的程序集访问共享队列,允许它操纵队列的其他成员并发现有关其他队列操作的信息。
第二遍是:
public interface IGameClient
{
void HandleStateChange(IGameState gameState);
GameActionDelegate event HasNewEvent; // passes IGameAction as a parameter
}
问题在于它不一定允许对动作进行排序或分组。
我真正希望的是能够传递对封装线程安全队列的对象的引用,但只暴露Enqueue()。但是,我担心不受信任的程序集可能会使用反射操作私有Queue对象。
那么,处理这个问题的最佳方法是什么?
答案 0 :(得分:2)
没有特别顺序的想法:
1)事件做保证订购(或者至少,您的实现可以保证您想要的任何订单,最简单的实现将保留订购)。
2)我不明白你为什么要在接口的第一个例子中通过引用传递队列。可能值得检查您是否理解parameter passing and "ref"。
3)如果你想出一个只暴露Enqueue的接口,那么实现可能不会 <{1}}。它可能包含一个Queue<T>
,但是如果你真的不相信程序集不要乱用你的私有成员,你应该以不授予它们的方式加载它们相关的反射权限。
另一种替代方法可能是传入Queue<T>
,当客户端想要将项目添加到队列时,可以调用该Action<IGameAction>
。代理将使用您拥有的任何Enqueue方法创建。
答案 1 :(得分:2)
根本不公开队列 - 只需在Facade上公开一个允许GameClient提交GameServer将放在内部队列中的条目的方法。
答案 2 :(得分:0)
您可以使HandleStateChange方法返回IEnumerable&lt; IGameAction&gt;,IList&lt; IGameAction&gt;或IGameAction []:
public interface IGameClient
{
IGameAction[] HandleStateChange(IGameState gameState);
}
然后使用该返回值将操作添加到队列中。
答案 3 :(得分:0)
传递一个新创建的队列实例,当HandleStateChange返回时,将虚拟队列中的东西合并到真实队列中。