Ok,
this is a more general "ugly critters in the corner" question. I am planning to start a project on WCF and PRISM. I have been playing around with PRISM some time know, and must say, I like it. Solid foundation for applications with nice possibilities to grow.
Now I want to incorporate WCF and build a distributed application, with one part on a server and two on the clients. It could be even the same machine, or not, depending on the scenario.
My idea is now to take the event concept from PRISM and extend it "over the wire" using WCF and callbacks, like described here WCF AlarmClock Callback Example.
I created a small picture to illustrate the idea (mainly for me), perhaps this makes things a little more clear:
The grey arrows stand for "using lib". The WCF-Event-Base meaning normal PRISM events, where the publish method is called "over the wire".
There are a few questions which come to mind:
- Are there any existing known examples for such things?
- What will be the best way to "raise" events over the wire?
- Any possible problems with this concept (the ugly critters mentioned earlier)
Regarding the second question, I currently think about raising the events using a string (the type of the concrete event I want to raise) and the payload as argument. Something like public void RaiseEvent(string eventType, object eventPayload){}
The payload needs to be serializeable, perhaps I even include a hashcheck. (Meaning if I raise e.g. an event with a picture as argument 10 times, I only transfer the picture once, afterwards using the hash to let the server use the buffer when publish)...
Ok, I think you get the idea. This "thing" should behave like a giant single application, using a kind of WCF_EventAggregator instead of the normal PRISM IEventAggregator. (wow, while writing I just got the idea to "simply" extend the IEventAggregator, have to think about this)...
Why do I write this? Well, for feedback mainly, and to sort my thoughts. So comments welcome, perhaps anything I should be "careful" about?
Chris
[EDITS]
Client distribution
There should be an undefined number of client, the server should not be aware of clients. The server itself can be a client to itself, raising strongly typed PRISM events in other parts of the source code.
The main difference between a "client" and a "server" is the actual implementation of the WCF_PRISM connector, see next chapter...
Client Event raising (PRISM feature)
In PRISM, to raise simple events you do NOT even need a reference to a service interface. The IEventAggregator can be obtained via dependency injection, providing an instance of the desired event (e.g. WeatherChangedEvent). This event can be raised by simply calling eventInstance.Publish(23) because the event is implemented as public class WeatherChangedEvent : CompositePresentationEvent<int>
WCF - PRISM Connector
As simple as raising events is subscribing to events. Every module can subsribe to events using the same technique, obtaining a reference and using Subscribe to attach to this event.
Here is now where the "magic" should happen. The clients will include a prism module responsible for connecting PRISM events to "wcf message sends". It will basically subsribe to all available events in the solution (they are all defined in the infrastructure module anyway) and send out a WCF message in case an event is raised.
The difference between a SERVER and a CLIENT is the implementation of this module. There needs to be a slight difference because of two things.
- The WCF setup settings
- The flow of events to prevent an infinite loop
The event flow will be (example)
- Client obtain ref to WeatherChangedEvent
- wChanged.Publish(27) --> normal PRISM event raising
- WCF_PRISM module is subscribed to event and
- send this event to the server
- Server internally gets instance of WeatherChangedEvent and publishes
- Server calls back to all clients raising their WeatherChangedEvent
Open Points
The obvious point is preventing a loop. If the server would raise the event in ALL clients, the clients would call back to the server, raising the event again, and so on... So there needs to be a difference between an event caused locally (which means I have to send it to the server) and a "server caused event" which means I do not have to send it to the server.
此外,如果客户端已启动了事件本身,它并不需要由服务器来调用,因为该事件已经得到提升(在客户端本身,2点)。
所有这些特殊行为将在WCF事件加注模块中封装,从应用程序的其他部分不可见。 我不得不思考“如何知道事件已出版的”,也许是一个GUID或类似这样的东西会是一个不错的主意。
而现在的第二大问题,什么我的目标是讲述“串”年初的时候在。 我不希望我每次添加一个事件的时间写一个新的服务接口定义。 在PRISM大多数事件是由一行中所定义,尤其是在发展中,我不想每次我添加了一个事件的时间来更新WCF_Event_Raising_Module。
我想过直接发送事件调用WCF时,使用功能与类似的签名例如:
public void RaiseEvent(EventBase e, object[] args)
问题是,我真的不知道,如果我可以序列PRISM事件容易。 他们都来自EventBase派生的,但我要检查这个......出于这个原因,我有想法,使用类型(如字符串),因为我知道服务器共享基础设施模块,可以获取自己的事件的实例(无需通过网络发送它,只有ARG)
到目前为止,到这里,我会继续开放更多的反馈的问题。 主要新的“洞察力”我刚:要想想递归/ infite循环问题。
顺便说一句。 如果有人完全被这一切事件的谈话混淆,给PRISM一试。 你会爱上它,即使你只使用DI及活动(如RegionManager是不是我的最爱)
克里斯
[END EDIT 1]