Héritage
Les exemples de code suivants montrent diverses utilisations de l'héritage dans un code managé pour créer une hiérarchie d'héritage dans WMI.
Héritage d'événement pour les classes dérivées de BaseEvent
Pour exposer des événements d'application à travers WMI, les développeurs doivent dériver ces événements de la classe système WMI __ExtrinsicEvent. Par défaut, lorsque vous dérivez une classe de System.Management.Instrumentation.BaseEvent, votre classe managée représente une classe WMI dérivée de __ExtrinsicEvent. Si vous continuez à dériver des classes de votre propre classe, ces dernières se refléteront dans une arborescence d'héritage d'événements WMI.
Tout événement de votre hiérarchie de classes d'événement managées peut être déclenché à partir du code managé. Ceci permet aux applications clientes de s'abonner à un vaste ensemble d'événements semblables ou à un seul événement étroitement spécialisé. Par exemple, si vous avez deux classes d'événement, MyBaseEvent et une classe dérivée MyDerivedEvent, la requête WQL "SELECT * FROM MyBaseEvent" permet à une application cliente d'intercepter les événements MyBaseEvent et MyDerivedEvent déclenchés à partir de votre application. D'un autre côté, un client émettant la requête WQL "SELECT * FROM MyDerivedEvent" ne voit rien lorsque votre application déclenche MyBaseEvent, mais reçoit des événements lorsque l'application déclenche MyDerivedEvent.
L'exemple de code suivant montre comment utiliser l'héritage pour créer une hiérarchie d'événements WMI simple en utilisant la classe d'assistance BaseEvent. La classe d'événement managé de plus haut niveau, TopEvent, est représentée par une classe WMI, TopEvent, dérivée de __ExtrinsicEvent. La classe TopEvent a deux enfants, Branch1Event et Branch2Event. Enfin, Branch1Event a deux enfants (Leaf1AEvent et Leaf1BEvent), et Branch2Event a un enfant (Leaf2AEvent). Cette hiérarchie d'événements est visualisée par le diagramme figurant dans le premier bloc de commentaires de l'exemple. À titre de référence, les classes les plus dérivées d'une hiérarchie (les classes dont aucune autre classe ne dérive) sont appelées nœuds sans descendant. Pour les hiérarchies d'événements, les nœuds sans descendant n'ont pas d'importance particulière, mais la distinction entre les nœuds sans descendant et les nœuds avec des descendants joue un rôle important dans l'instrumentation d'instance.
Pour simplifier, les événements de cet exemple n'ont pas de propriétés. Dans la pratique, il est probable que vous doterez chaque classe enfant de propriétés supplémentaires, ce que le code suivant omet de faire dans un souci de concision.
using System;
using System.Management.Instrumentation;
[assembly:Instrumented]
// A simple tree of events derived from BaseEvent
// TopEvent--Branch1Event--Leaf1AEvent
// \ \-Leaf1BEvent
// \
// Branch2Event--Leaf2AEvent
// Any event in the hierarchy can be raised by the application
// This class inherits the 'InstrumentationType.Event' attribute
// from 'BaseEvent'
public class TopEvent : BaseEvent {
}
// This class inherits the 'InstrumentationType.Event' attribute
public class Branch1Event : TopEvent{
}
// This class inherits the 'InstrumentationType.Event' attribute
public class Leaf1AEvent : Branch1Event {
}
// This class inherits the 'InstrumentationType.Event' attribute
public class Leaf1BEvent : Branch1Event {
}
// This class inherits the 'InstrumentationType.Event' attribute
public class Branch2Event : TopEvent {
}
// This class inherits the 'InstrumentationType.Event' attribute
public class Leaf2AEvent : Branch2Event {
}
class App {
static void Main(string[] args) {
// Raise each type of event
new TopEvent().Fire();
new Branch1Event().Fire();
new Leaf1AEvent().Fire();
new Leaf1BEvent().Fire();
new Branch2Event().Fire();
new Leaf2AEvent().Fire();
}
}
Héritage d'événement pour les classes qui ne sont pas dérivées de BaseEvent
Au lieu de dériver la classe d'événement de plus haut niveau de la classe d'assistance System.Managment.Instrumentation.BaseEvent, les développeurs peuvent marquer une classe avec l'attribut [InstrumentationClass(InstrumentationType.Event)]. Il suffit de faire cette opération sur la classe d'événement de plus haut niveau. En effet, les classes dérivées d'une classe possédant cet attribut sont elles aussi interprétées comme classes d'instrumentation. Techniquement, ceci est dû au fait que l'attribut InstrumentationClass se transmet automatiquement par héritage aux classes dérivées. En fait, cet attribut était superflu dans l'exemple (où les événements dérivaient de BaseEvent) parce que BaseEvent lui-même possède l'attribut InstrumentationClass qui se transmet par héritage à tous ses enfants.
L'exemple suivant effectue les mêmes tâches que le précédent, mais emploie l'attribut InstrumentationClass au lieu d'une dérivation à partir de **BaseEvent **:
using System;
using System.Management.Instrumentation;
[assembly:Instrumented]
// A simple tree of events declared with attributes
// TopEvent2--Branch1Event2--Leaf1AEvent2
// \ \-Leaf1BEvent2
// \
// Branch2Event2--Leaf2AEvent2
// Any event in the hierarchy can be raised by the application
// This is a top-level event class
[InstrumentationClass(InstrumentationType.Event)]
public class TopEvent2 {
}
// This class inherits the 'InstrumentationType.Event' attribute
public class Branch1Event2 : TopEvent2{
}
// This class inherits the 'InstrumentationType.Event' attribute
public class Leaf1AEvent2 : Branch1Event2 {
}
// This class inherits the 'InstrumentationType.Event' attribute
public class Leaf1BEvent2 : Branch1Event2 {
}
// This class inherits the 'InstrumentationType.Event' attribute
public class Branch2Event2 : TopEvent2 {
}
// This class inherits the 'InstrumentationType.Event' attribute
public class Leaf2AEvent2 : Branch2Event2 {
}
class App {
static void Main(string[] args) {
// Raise each type of event
Instrumentation.Fire(new TopEvent2());
Instrumentation.Fire(new Branch1Event2());
Instrumentation.Fire(new Leaf1AEvent2());
Instrumentation.Fire(new Leaf1BEvent2());
Instrumentation.Fire(new Branch2Event2());
Instrumentation.Fire(new Leaf2AEvent2());
}
}
Héritage d'instance pour les classes dérivées de Instance
La création de hiérarchies d'instances n'est pas sans rappeler celle des hiérarchies d'événements. La principale différence, toutefois, est que les événements WMI de plus haut niveau sont dérivés de la classe WMI __ExtrinsicEvent, et que les instances de plus haut niveau n'ont pas de classe parent (ou surclasse dans la terminologie WMI). Lorsque vous réalisez une instrumentation d'instance simple en dérivant une classe de la classe d'assistance System.Management.Instrumentation.Instance, la classe WMI apparaît comme une seule classe d'instance de plus haut niveau.
Les hiérarchies d'instances, cependant, sont légèrement plus complexes. Dans la version actuelle de System.Management, seuls les nœuds sans descendant d'une hiérarchie d'instances peuvent réellement prendre en charge la publication d'instances. Les nœuds avec des descendants sont considérés comme des classes WMI abstraites. En d'autres termes, si vous avez deux classes, BaseInstance et une classe dérivée DerivedInstance, vous pouvez créer des instances de la classe DerivedInstance mais non de la classe BaseInstance. Les classes capables de prendre en charge des instances sont communément appelées classes concrètes. La règle d'héritage pour l'instrumentation d'instance peut ensuite être formulée de la façon suivante : seuls les nœuds sans descendant d'une hiérarchie d'héritage peuvent être des classes d'instance concrètes. Tous les autres nœuds de la hiérarchie doivent être marqués comme classes WMI abstraites.
Une classe est marquée comme classe d'instrumentation WMI abstraite si elle possède l'attribut [InstrumentationClass(InstrumentationType.Abstract)]. La classe d'assistance Instance est marquée avec l'attribut [InstrumentationClass(InstrumentationType.Instance)], qui se propage vers les classes enfant par défaut. Ceci ne pose pas de problème si vous avez une seule classe d'instance concrète de plus haut niveau, mais avec une hiérarchie plus complexe, vous devez ajouter manuellement l'attribut Abstract à la classe de plus haut niveau. L'exemple suivant montre une hiérarchie qui utilise cette technique. La classe de plus haut niveau, TopInstance, est dérivée de Instance et marquée explicitement avec l'attribut Abstract. Les classes dérivées qui ne sont pas des nœuds sans descendant héritent correctement cet attribut (et deviennent des classes WMI abstraites comme TopInstance). Les nœuds sans descendant doivent être marqués comme instances concrètes et, par conséquent, possèdent des attributs Instance explicites sur leurs définitions de classe.
using System;
using System.Management.Instrumentation;
[assembly:Instrumented]
// A simple tree of instances derived from Instance
// TopInstance--Branch1Instance--Leaf1AInstance
// \ \-Leaf1BInstance
// \
// Branch2Instance--Leaf2AInstance
// Only the leafs of the tree can be concrete instances.
// All other nodes on the tree must be abstract.
// This is a top-level abstract class. It must have the
// 'InstrumentationType.Abstract' attribute or it would
// inherit the 'Instance' attribute from the base class 'Instance'
[InstrumentationClass(InstrumentationType.Abstract)]
public class TopInstance : Instance {
}
// This class inherits the 'InstrumentationType.Abstract' attribute
public class Branch1Instance : TopInstance {
}
// This is a leaf class which can be concrete
[InstrumentationClass(InstrumentationType.Instance)]
public class Leaf1AInstance : Branch1Instance {
}
// This is a leaf class which can be concrete
[InstrumentationClass(InstrumentationType.Instance)]
public class Leaf1BInstance : Branch1Instance {
}
// This class inherits the 'InstrumentationType.Abstract' attribute
public class Branch2Instance : TopInstance {
}
// This is a leaf class which can be concrete
[InstrumentationClass(InstrumentationType.Instance)]
public class Leaf2AInstance : Branch2Instance {
}
class App {
static void Main(string[] args) {
// Publish an instance of each leaf
Leaf1AInstance leaf1a = new Leaf1AInstance();
Leaf1BInstance leaf1b = new Leaf1BInstance();
Leaf2AInstance leaf2a = new Leaf2AInstance();
leaf1a.Published = true;
leaf1b.Published = true;
leaf2a.Published = true;
// Instances now visible through WMI
Console.WriteLine("Instances now visible through WMI");
Console.ReadLine();
// Revoke all instances
leaf1a.Published = false;
leaf1b.Published = false;
leaf2a.Published = false;
}
}
Héritage d'instance pour les classes qui ne sont pas dérivées de Instance
Si vous utilisez seulement des attributs pour déclarer des classes d'instrumentation d'instance, les hiérarchies se définissent selon une méthode semblable à celle employée pour les classes d'instrumentation d'instance dérivées de la classe d'assistance System.Management.Instrumentation.Instance. Encore une fois, la classe d'instrumentation d'instance de plus haut niveau doit être marquée avec [InstrumentationClass(InstrumentationType.Abstract)], sauf si vous n'avez qu'une seule classe d'instance concrète de plus haut niveau. Comme les branches de la hiérarchie héritent cet attribut, elles n'ont pas besoin de déclarer explicitement leur propre attribut InstrumentationClass. Une fois encore, vous devez marquer explicitement les nœuds sans descendant comme classes d'instance WMI concrètes et leur ajouter l'attribut [InstrumentationClass(InstrumentationType.Instance)].
L'exemple suivant montre les mêmes fonctionnalités que le précédent, mais n'utilise que l'attribut InstrumentationClass au lieu de dériver la classe de plus haut niveau de la classe d'assistance Instance.
using System;
using System.Management.Instrumentation;
[assembly:Instrumented]
// A simple tree of instances declared with attributes
// TopInstance2--Branch1Instance2--Leaf1AInstance2
// \ \-Leaf1BInstance2
// \
// Branch2Instance2--Leaf2AInstance2
// Only the leafs of the tree can be concrete instances.
// All other nodes on the tree must be abstract.
// This is a top level abstract class.
[InstrumentationClass(InstrumentationType.Abstract)]
public class TopInstance2 {
}
// This class inherits the 'InstrumentationType.Abstract' attribute
public class Branch1Instance2 : TopInstance2{
}
// This is a leaf class which can be concrete
[InstrumentationClass(InstrumentationType.Instance)]
public class Leaf1AInstance2 : Branch1Instance2 {
}
// This is a leaf class which can be concrete
[InstrumentationClass(InstrumentationType.Instance)]
public class Leaf1BInstance2 : Branch1Instance2 {
}
// This class inherits the 'InstrumentationType.Abstract' attribute
public class Branch2Instance2 : TopInstance2 {
}
// This is a leaf class which can be concrete
[InstrumentationClass(InstrumentationType.Instance)]
public class Leaf2AInstance2 : Branch2Instance2 {
}
class App {
static void Main(string[] args) {
// Publish an instance of each leaf
Leaf1AInstance2 leaf1a = new Leaf1AInstance2();
Leaf1BInstance2 leaf1b = new Leaf1BInstance2();
Leaf2AInstance2 leaf2a = new Leaf2AInstance2();
Instrumentation.Publish(leaf1a);
Instrumentation.Publish(leaf1b);
Instrumentation.Publish(leaf2a);
// Instances now visible through WMI
Console.WriteLine("Instances now visible through WMI");
Console.ReadLine();
// Revoke all instances
Instrumentation.Revoke(leaf1a);
Instrumentation.Revoke(leaf1b);
Instrumentation.Revoke(leaf2a);
}
}
Voir aussi
Instrumentation des applications .NET Framework avec System.Management | Classes et mappage dans CLI et WMI | Exposition d'événements de gestion | Exposition de données de gestion | Inscription du schéma pour une application instrumentée