PRISM和WCF - 难道他们发挥好?(PRISM and WCF - Do they play

2019-08-21 04:27发布

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)

  1. Client obtain ref to WeatherChangedEvent
  2. wChanged.Publish(27) --> normal PRISM event raising
  3. WCF_PRISM module is subscribed to event and
  4. send this event to the server
  5. Server internally gets instance of WeatherChangedEvent and publishes
  6. 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]

Answer 1:

这是一个非常有趣的方法。 我会说这里只有两件事情:

  1. 你真是自讨苦吃,如果你使用字符串和对象参数 。 强类型EventAggregator事件(从CompositeEvent继承)是去这里的路。 如果你这样做,可维护性将走一路上扬。
  2. 你为你的WCF模型- > EventAggregator应该考虑一切从EventAggregator为“事件”和我的一切/从WCF服务的“信息”。 你应该真正考虑的是,你基本上是一个翻译事件EventAggregator的消息,而不是问这个问题:“我怎么养WCF事件”。

我觉得你在做什么是可行的。 看着你实现我真的很喜欢你是如何考虑这个问题。


轻微替代(W /强类型)

我想扔一点东西在那里,看你怎么想吧......也许它会稍稍影响你的设计。 具体而言,这是旨在解决上述第一点,并与强类型走得更远。

您是否考虑过你的服务接口的EventAggregator支持的实现? 让我们在你的例子说,你有,你正在使用的IWeatherService WCF服务。 目前,据我所知,您的使用将是这个样子:

  1. 客户端使用WCF事件客户端库,并调用的RaiseEvent(“ChangeWeather”,Weather.Sunny);
  2. 在WCF事件客户端库转化为对WCF服务等待收到此消息,使用IWeatherService通道接口这样做适当的调用此。 可能有一个大的讨厌的switch语句基于方法调用的名称。

为什么不稍微修改此。 让IWeatherService在所有的服务器和客户端的共享合同。 该服务器将有实际执行中,很明显,但客户端将有EventAggregator支持的实现,去一个中央的代理是队列和消息发送给服务器。

编写上升到由中央消息代理接收并抛出,落实在你的容器,为客户使用事件IWeatherService的EventAggregator支持的实现。

public ClientWeatherService : IWeatherService
{

    IEventAggregator _aggregator;
    public ClientWeatherService(IEventAggregator aggregator) 
    { 
        _aggregator = aggregator; 
    }

    public void ChangeWeather(Weather weather)
    {
        ChangeWeatherEvent cwEvent = _aggregator.GetEvent<ChangeWeatherEvent>();
        cwEvent.Publish(weather);
    }
}

从那里,而不是直接使用“WCF事件客户端库”,他们直接使用IWeatherService,不知道它不会调用实际服务。

public MyWeatherViewModel : ViewModel
{
    IWeatherService _weatherService;
    public MyWeatherViewModel(IWeatherService weatherService)
    {
        _weatherService = weatherService;
    }
}

然后,你就会有一些事件处理程序设置,使WCF调用到真正的服务,但现在你必须从客户的强类型的好处。

只是一个想法。

我真的很喜欢这个类型的问题。 我希望更多的人会问这种事情#2。 获取大脑在上午运动:)



Answer 2:

这似乎是一个复杂的解决问题的方法。

你是从客户端应用程序引发事件,或者使用回调合同从服务提升活动? 或两者?

我会在客户端的简单服务类处理这个。 它可以实现回调协定,并为每个回调方法可以提高只是一个局部事件棱镜在客户端的任何用户。 如果您需要提高由该服务处理事件,那么服务类可以订阅这些事件并调用WCF服务。

所有你需要的真的是抽象的WCF服务从客户端离开的细节一类,并公开它通过棱镜事件的接口。

我个人并不希望修改/扩展基础架构组件,并创建对混凝土WCF服务的依赖。



文章来源: PRISM and WCF - Do they play nice?
标签: wcf events Prism