In my. IOC, you can subscribe to the objectbuilderregistered and objectbuilderunregistering events to receive notifications during service logout/registration. However, there are also some shortcomings in using these two events. First, they can only send notifications for services currently registered/deregistered, and activation/deactivation events for upper-level services that depend on the current service (caused by registration/deregistration of the current service ), they are powerless. Second, they are broadcast events for all registered items. That is to say, the container will send a notification to all the event handler processes that have subscribed to the two events, no matter what services are registered/deregistered.
Due to the above restrictions, we provide the iobjectobserver/iobjectcollectionobserver mechanism in my. IOC. With iobjectobserver/iobjectcollectionobserver, you can achieve more efficient and real-time listening for a specific contract type.
In both cases, iobjectobserver listens for a service that implements a certain contract, while iobjectcollectionobserver listens for a group of services that implement the same contract. The following sample code is used to understand their usage:
using System;using System.Collections.Generic;using My.Ioc;namespace ObserverUsage{ #region ObjectObserver Types public class ServiceConsumer { Service _service; public ServiceConsumer(Service service) { _service = service; } } public class Service { } #endregion #region ObjectCollectionObserver Types public class Tree { readonly IList<Node> _childNodes; public Tree(IList<Node> childNodes) { _childNodes = new List<Node>(childNodes); } public IList<Node> ChildNodes { get { return _childNodes; } } } public abstract class Node { string _name; public string Name { get { _name = _name ?? GetType().Name; return _name; } } } public class Node1 : Node { } public class Node2 : Node { } public class Node3 : Node { } public class Node4 : Node { } #endregion class Program { private static IObjectContainer _container; static void Main(string[] args) { _container = new ObjectContainer(false); RunObjectObserverTest(); RunObjectCollectionObserverTest(); Console.ReadLine(); } #region ObjectObserver static void RunObjectObserverTest() { IObjectRegistration<Service> serviceRegistration; IObjectObserver<ServiceConsumer> consumerObserver; IObjectObserver<Service> serviceObserver; // Register and commit _container.Register<Service>().Return(out serviceRegistration); _container.Register<ServiceConsumer>(); _container.CommitRegistrations(); // Try to get the ObjectObserver and hook events if (_container.TryGetObserver(out serviceObserver)) serviceObserver.Changed += OnObjectBuilderChangedForService; if (_container.TryGetObserver(out consumerObserver)) consumerObserver.Changed += OnObjectBuilderChangedForConsumer; // Try to resolve an instance of ServiceConsumer to build the relationship between the // ServiceConsumer and Service, so that if we unregistered the Service, not only the // service observer, but also the consumer observer, will receive the notification. var consumer = _container.Resolve<ServiceConsumer>(); // Unregister the Service. The observers should receive the notification later. _container.Unregister(serviceRegistration); // Dispose the observers consumerObserver.Dispose(); serviceObserver.Dispose(); } static void OnObjectBuilderChangedForService(ObjectBuilderChangedEventArgs args) { if (args.ChangeMode == ObjectBuilderChangeMode.Activate) Console.WriteLine("The Service is activated..."); else if (args.ChangeMode == ObjectBuilderChangeMode.Deactivate) Console.WriteLine("The Service is deactivated..."); } static void OnObjectBuilderChangedForConsumer(ObjectBuilderChangedEventArgs args) { if (args.ChangeMode == ObjectBuilderChangeMode.Activate) Console.WriteLine("The ServiceConsumer is activated..."); else if (args.ChangeMode == ObjectBuilderChangeMode.Deactivate) Console.WriteLine("The ServiceConsumer is deactivated..."); } #endregion #region ObjectCollectionObserver private static Tree _tree; static void RunObjectCollectionObserverTest() { IObjectRegistration<Node> nodeRegistration; IObjectCollectionObserver<Node> nodesObserver; // Register and commit _container.Register<Node, Node1>().Return(out nodeRegistration); _container.Register<Node, Node2>(); _container.Register<Node, Node3>(); _container.Register<Node, Node4>(); _container.CommitRegistrations(); // Try to get the ObjectObserver and hook events if (_container.TryGetObserver(out nodesObserver)) nodesObserver.Changed += OnObjectBuilderChangedForNodeCollection; var nodes = _container.ResolveAll(nodesObserver); _tree = new Tree(nodes); PrintTree(); // Unregister the Service. The observers should receive the notification later. _container.Unregister(nodeRegistration); PrintTree(); _container.Register<Node, Node1>(); _container.CommitRegistrations(); PrintTree(); // Dispose the observer nodesObserver.Dispose(); } static void PrintTree() { Console.WriteLine(); foreach (var node in _tree.ChildNodes) Console.WriteLine(node.Name); } static void OnObjectBuilderChangedForNodeCollection(ObjectBuilderCollectionChangedEventArgs args) { if (args.ChangeMode == ObjectBuilderCollectionChangeMode.Add) { var node = (Node)_container.Resolve(args.ObjectBuilder, null); _tree.ChildNodes.Add(node); } else if (args.ChangeMode == ObjectBuilderCollectionChangeMode.Remove) { _tree.ChildNodes.RemoveAt(args.Position); } } #endregion }}
View code
In the preceding example, we briefly demonstrate how to use iobjectobserver/iobjectcollectionobserver.
As you can see in the example, when iobjectobserver is used, when the service is disabled (deregistered)/activated (registered), the observer of the service (observer) any observer of the Upper-layer service dependent on the Service will receive a notification, and the user can execute some operations in the processing program at this time to better respond to service changes.
Compared with iobjectobserver, iobjectcollectionobserver has a slightly different usage because it listens on a group rather than a service. When iobjectcollectionobserver is used, when a service is registered/deregistered, if the service or any of its upper-level services are listened on by iobjectcollectionobserver, iobjectcollectionobserver will send a notification, in this way, we will know the position in the collection where the service is disabled (deregistered)/activated (registered, this allows you to perform operations in the handler Based on the notification information to update (delete/Add) the Service Set (node tree in the example)
The source code of this article can be downloaded from this place.
My. IOC sample code -- use the observer mechanism to capture registry status changes