ArticleDirectory
-
- 9.4.1 ieventaggregator
- 9.4.2 compositepresentationevent
- 9.4.3 create and release events
- 9.4.3 subscribe to events
This section introduces:
This section describes how to useEventaggregatorProvides inter-module communication.
2012-2-3
9.4 event Aggregation
Prism provides an event mechanism to take the loose coupling between modules as possible. In this mechanism, based on the event aggregation service, subscribers and publishers can communicate without mutual reference.
EventaggregatorProvides the multi-channel broadcast Publisher/subscriber function. That is to say, multiple publishers can publish the same event or the same event, which can be monitored by multiple subscribers. Consider usingEventaggregatorPublish events to ensure that messages can be stored in business logic such as controllers or performers.Code.
For example, in the stock trader Ri, whenProcess OrderIn this case, other modules need to know that the order has been successfully submitted so that they can update their view.
The event created by prism is a strongly typed event, that is, the type check will be applied to the event during compilation.ProgramErrors can be found before running. In prism,EventaggregatorAllows a subscriber or publisher to specify a specificEventbase. Event aggregators are applicable to multiple publishers and subscribers, as shown in.
Note ]:About. NET FrameworkEvent
Events using the. NET Framework are the easiest and most direct cross-module communication method without loose coupling .. Net Framework events implement the publisher-subscriber mode. However, to subscribe to an object event, you need to directly reference this object. In complex programs, this object is often in other modules. This will lead to a tightly coupled design. Therefore,. NET Framework events are used for intra-module communication rather than inter-module communication.
When using. NET Framework events, you must be very careful about memory leakage. In particular, when static classes or long-lived components subscribe to events of non-static classes or short-lived components. If the subscriber does not cancel the subscription, the publisher remains valid, and the garbage collection mechanism cannot recycle the publisher.
9.4.1 ieventaggregator
EventaggregatorIn the container,IeventaggregatorAPI. The event aggregator collects and locates events and saves an event set in the system.
Public InterfaceIeventaggregator
{
Teventtype getevent <teventtype> ()WhereTeventtype: eventbase;
}
InEventaggregatorIf no constructor is constructed, an event is constructed if it is accessed. This operation removes the event publisher and subscriber from the status to be monitored, regardless of whether the event is available. ([This pronoun, refersEventaggregator] [Relieves <the publisher or subscriber> from <needing to determine needs to be monitored. Currently, the needing table is active, content being monitored by the system> remove XXX from XXX] [whether the event is available regardless of whether the event is available].)
9.4.2 compositepresentationevent
The actual operator of the connection between the publisher and the subscriber isCompositepresentationeventClass. It is unique in PrismEventbase. This class maintains the subscriber list and publishes events to subscriber.
CompositepresentationeventIs a generic class. As a generic class, a load type is required for definition. This helps check that the correct method is provided between the subscriber and the publisher during compilation to ensure the event connection. The following code is:Compositepresentationevent.
Public Class Compositepresentationevent <tpayload>: eventbase
{
...
Public Subscriptiontoken subscribe (Action <tpayload> action );
Public Subscriptiontoken subscribe (Action <tpayload> action, threadoption );
Public Subscriptiontoken subscribe (Action <tpayload> action, Bool Keepsubscriberreferencealive)
Public Virtual Subscriptiontoken subscribe (Action <tpayload> action, threadoption, Bool Keepsubscriberreferencealive );
Public Virtual Subscriptiontoken subscribe (Action <tpayload> action, threadoption, Bool Keepsubscriberreferencealive, predicate <tpayload> filter );
Public Virtual Void Publish (tpayload payload );
Public Virtual Void Unsubscribe (Action <tpayload> subscriber );
Public Virtual Bool Contains (Action <tpayload> subscriber)
...
}
9.4.3 create and release events
The following describes how to useIeventaggregatorInterface creation, publishing, and subscriptionCompositepresentationevent.
1) Create an event
Compositepresentationevent <tpayload>The design intent is to become the base class of the application or module-specific events.TpayloadIs the type of event load content. The load content refers to the parameters that need to be passed to the subscriber after the event is published.
For example, the following code is in the stock trader reference implementation (stock trader RI)Tickersymbolselectedevent. The load content is a string containing company symbol. Note that the implementation of this class is empty.
Public ClassTickersymbolselectedevent: compositepresentationevent <String> {}
[Note]: in complex projects, events need to be frequently used in multiple modules, so they are defined in a shared place. In the stock trader RiStocktraderri. Infrastructure(Annotation, infrastructureIs the meaning of the basic structure)Project.
2) release events
Publisher passedEventaggregatorCheck the event and callPublishMethod release. AddIeventaggregatorType parameters can be accessed by using dependency InjectionEventaggregator.
The following example shows the releaseTickersymbolselectedevent.
This. Eventaggregator. getevent <tickersymbolselectedevent> (). Publish ("Stock0");
9.4.3 subscribe to events
Subscriber usesCompositepresentationeventClassSubscribeMethod. SubscriptionCompositepresentationeventsThere are many methods. The following standards can help you decide.
L if the UI element needs to be updated when an event is triggered, subscribe to it in the UI thread.
L to filter events, a filtering delegate is provided during subscription.
L if you need to pay attention to the performance of the event, use the strongly delegated reference during subscription and then manually cancel the subscription.Compositepresentationevent.
L If none of the above conditions applies, use the default configuration.
These situations are described below.
1) subscribe in the UI thread
Generally, the subscriber must update the elements in the UI when responding to events. In WPF and Silverlight, only the UI thread can update the UI element.
By default, the subscriber receives the event in the publisher's thread. If the publisher sends an event in the UI thread, the subscriber can update the UI element. However, if the publisher's thread is a background thread, the subscriber cannot directly update the UI element. In this case, the subscriber needs to useDispatcherClass to update the UI elements at a specified time.
Provided by PrismCompositepresentationeventClass to help subscriber automatically receive events in the UI thread. The subscriber only needs to explain this situation during subscription.
Public VoidRun ()
{
...
This. Eventaggregator. getevent <tickersymbolselectedevent> (). subscribe (shownews, threadoption. uithread );
);
}
Public VoidShownews (StringCompanysymbol)
{
This. Articlepresentationmodel. settickersymbol (companysymbol );
}
ThreadoptionThe following options are provided:
LPublisherthread. This setting allows events to be received in the publisher's thread. This is the default setting.
LBackgroundthread. This setting will receive events asynchronously in the. NET Framework thread pool.
LUithread. This setting will receive events on the UI thread.
2) Subscription Filtering
The subscriber may not need to process all objects of published events. In this case, the subscriber can useFilterParameters.FilterYesSystem. predicate <tpayload>Type parameter. It is a delegate that determines whether an event requires a subscriber response by determining whether the load content meets a series of conditions. If the load content does not meet the conditions, the subscriber's callback function will not be executed.
Filters are generally provided by a Lambda expression, as shown below.
Fundaddedevent =This. Eventaggregator. getevent <fundaddedevent> ();
Fundaddedevent. subscribe (fundaddeventhandler, threadoption. uithread,False,
Fundorder => fundorder. customerid =This. Customerid );
[Note]: Silverlight does not support weak referenced lambda expressions or anonymous delegation.
In Silverlight, you need to call an independent public method, as shown below.
Public BoolFundorderfilter (fundorder)
{
ReturnFundorder. customerid =This. Customerid;
}
...
Fundaddedevent =This. Eventaggregator. getevent <fundaddedevent> ();
Subscriptiontoken = fundaddedevent. subscribe (fundaddedeventhandler, threadoption. uithread,False, Fundorderfilter );
Note ]:SubscribeReturns a data typeMicrosoft. Practices. Prism. Events. subscriptiontokenTo remove the event subscription. This token is useful when the callback function is an anonymous delegate or Lambda expression or when you subscribe to the same event using different filters.
[Note]: it is not recommended to modify the load object in the Event Callback Function because there will be multiple threads simultaneously writing the load object. You must ensure that the load object remains unchanged to avoid concurrent errors.
3) subscribe through forced Delegation
If you trigger multiple performance events in a short period of time, you may need to subscribe them in the form of strongly delegated references. To subscribe to events in this way, you must manually cancel the subscription when releasing the subscriber.
By default,CompositepresentationeventWeak delegate references of subscribers and filters are maintained during subscription. That is to sayCompositepresentationeventThe reference in does not prevent the garbage collection mechanism from revoking subscribers. The use of weak delegate references prevents subscribers from unsubscribe and garbage collection.
Of course, maintaining a weak delegate reference is slower than a general strong reference. In most applications, you do not need to pay special attention to the performance. However, if a large number of events are published by the application in a short time, you needCompositepresentationeventUse strong references. If a strongly-delegated reference is used, you need to subscribe to events when the subscription object is not needed so that garbage collection can act on the subscription object.
To subscribe to strongly referenced eventsSubscribeUse in MethodKeepsubscriberreferencealiveParameters are as follows.
Fundaddedevent = eventaggregator. getevent <fundaddedevent> ();
BoolKeepsubscriberreferencealive =True;
Fundaddedevent. subscribe (fundaddeventhandler, threadoption. uithread, keepsubscriberreferencealive, fundorder => fundorder. customerid = _ customerid );
KeepsubscriberreferencealiveThe parameter isBoolType.
L when setTrueThe event instance keeps a strong reference to the subscriber, so that the subscriber will not be recycled. For more information about how to cancel a subscription, see the "unsubscribe events" section mentioned later.
L when setFalse(This is the default value when the parameter is omitted), the event will maintain the weak reference of the subscriber object, so that garbage collection is allowed to automatically translate the object when the subscriber object is no longer referenced by other objects. When the subscriber is recycled, the subscription is automatically canceled.
4) default subscription
When subscribing with the default value, the subscriber must provide a callback method with the correct function prototype to receive Event Notifications. For example,TickersymbolselectedeventThe handler must have a string parameter, as shown below.
Public VoidRun ()
{
...
This. Eventaggregator. getevent <tickersymbolselectedevent> (). subscribe (shownews );
}
Public VoidShownews (StringCompanysymbol)
{
Articlepresentationmodel. settickersymbol (companysymbol );
}
5) cancel subscription events
If the subscriber no longer needs to receive events, you can use the subscriber or subscription information to cancel the subscription.
The following example shows how to cancel a subscription directly.
Fundaddedevent =This. Eventaggregator. getevent <fundaddedevent> ();
Fundaddedevent. subscribe (fundaddeventhandler, threadoption. publisherthread );
Fundaddedevent. Unsubscribe (fundaddeventhandler );
The following example shows how to use the subscription token to cancel a subscription. This token isSubscribeMethod.
Fundaddedevent =This. Eventaggregator. getevent <fundaddedevent> ();
Subscriptiontoken = fundaddedevent. subscribe (fundaddedeventhandler, threadoption. uithread,False, Fundorder => fundorder. customerid =This. Customerid );
Fundaddedevent. Unsubscribe (subscriptiontoken );