Ereditarietà

Nei seguenti esempi di codice vengono mostrate alcune piccole varianti nell'utilizzo dell'ereditarietà nel codice gestito per creare una gerarchia di ereditarietà in WMI.

Ereditarietà di eventi per classi derivate da BaseEvent

Se gli sviluppatori desiderano esporre gli eventi di applicazione tramite WMI, è necessario che questi eventi siano derivati dalla classe di sistema __ExtrinsicEvent di WMI. Per impostazione predefinita, quando si deriva una classe da System.Management.Instrumentation.BaseEvent, la propria classe gestita rappresenta una classe di WMI derivata da __ExtrinsicEvent. Se si derivano ulteriormente classi dalla propria classe, queste saranno riprodotte con mirroring in una struttura di ereditarietà di eventi di WMI.

Dal codice gestito è possibile generare qualsiasi evento nella gerarchia di classi di eventi gestiti. In tal modo, le applicazioni client possono sottoscrivere un vasto insieme di eventi simili oppure un singolo evento specifico specializzato. Se si hanno, ad esempio, due classi di evento, MyBaseEvent e una classe derivata MyDerivedEvent, la query WQL "SELECT * FROM MyBaseEvent" consente a un'applicazione client di intercettare entrambi gli eventi, MyBaseEvent e MyDerivedEvent, generati dall'applicazione dell'utente. D'altra parte, un client che esegue la query WQL "SELECT * FROM MyDerivedEvent" non visualizzerà nulla quando l'applicazione genera MyBaseEvent, ma otterrà eventi quando genera MyDerivedEvent.

Nell'esempio di codice seguente viene mostrato come utilizzare l'ereditarietà per creare una semplice gerarchia di eventi WMI tramite la classe di supporto BaseEvent. La classe di evento gestito di livello più alto, TopEvent, è rappresentata da una classe WMI, TopEvent, derivata da __ExtrinsicEvent. La classe TopEvent avrà due eventi figlio, Branch1Event e Branch2Event. Infine, ci saranno due eventi figlio di Branch1Event (Leaf1AEvent e Leaf1BEvent), e un evento figlio di Branch2Event (Leaf2AEvent). Per visualizzare questa gerarchia di eventi, è possibile esaminare il diagramma nel primo blocco di commenti dell'esempio. Per motivi di riferimento, le classi maggiormente derivate all'interno di una gerarchia, ovvero le classi che non presentano ulteriori classi da esse derivate, vengono definite nodi foglia. Per le gerarchie di eventi, i nodi foglia non hanno particolare importanza, ma la distinzione tra nodi foglia e nodi non foglia ha un ruolo importante per la strumentazione di istanze.

Per semplicità, gli eventi non hanno proprietà. Nella pratica, è probabile che l'utente debba ampliare ogni classe figlio con proprietà aggiuntive, ma questo viene omesso nell'esempio di codice seguente, per questioni di brevità.

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();
    }
}

Ereditarietà di eventi per classi non derivate da BaseEvent

Un'alternativa alla derivazione della classe di evento di primo livello dalla classe di supporto System.Managment.Instrumentation.BaseEvent è rappresentata dalla possibilità per gli sviluppatori di contrassegnare una classe con l'attributo [InstrumentationClass(InstrumentationType.Event)], operazione necessaria solo per la classe di evento di livello superiore. Le classi derivate da una classe con questo attributo saranno interpretate anche come classi di evento con strumentazione. Si noti che questo risultato si ottiene perché l'attributo InstrumentationClass viene ereditato automaticamente da classi derivate. In effetti, questo attributo non è mai stato necessario nell'esempio sugli eventi derivati da BaseEvent, perché la stessa classe BaseEvent dispone dell'attributo InstrumentationClass che viene ereditato da tutti i propri attributi figlio.

Nell'esempio seguente viene eseguita la stessa operazione dell'esempio precedente, ma viene utilizzato l'attributo InstrumentationClass anziché la derivazione da 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());
    }
}

Ereditarietà di istanze per classi derivate da Instance

La creazione di gerarchie di istanze ha molti aspetti in comune con quella delle gerarchie di eventi. La differenza principale consiste nel fatto che gli eventi di WMI di livello superiore sono derivati dalla classe WMI __ExtrinsicEvent, e le istanze di livello superiore non hanno classi padre, dette anche superclassi nella terminologia di WMI. Quando si esegue la strumentazione di una semplice istanza tramite la derivazione di una sola classe dalla classe di supporto System.Management.Instrumentation.Instance, la classe di WMI viene vista come una singola classe di istanza di livello superiore.

Tuttavia, le gerarchie di istanze sono leggermente più complesse. Nella versione corrente di System.Management solo i nodi foglia di una gerarchia di istanza possono effettivamente supportare la pubblicazione di istanze. I nodi non foglia sono considerati classi WMI astratte. In altre parole, se si hanno due classi, BaseInstance e una classe derivata DerivedInstance, è possibile creare istanze di DerivedInstance ma non di BaseInstance. Un altro termine comunemente utilizzato per descrivere le classi che supportano le istanze è classe concreta. Quindi, la regola di ereditarietà per la strumentazione di istanze può essere espressa nel modo seguente: solo i nodi foglia di una gerarchia di ereditarietà possono essere classi di istanza concrete. Tutti gli altri nodi della gerarchia devono essere contrassegnati come classi WMI astratte.

Per contrassegnare una classe come classe di strumentazione astratta di WMI, è necessario avere l'attributo [InstrumentationClass(InstrumentationType.Abstract)]. La classe di supporto Instance viene contrassegnata da [InstrumentationClass(InstrumentationType.Instance)], che, per impostazione predefinita, si propaga alle classi figlio. Questa propagazione va bene se si dispone di una singola classe concreta di istanza di livello superiore, ma con una gerarchia più complessa è necessario aggiungere manualmente l'attributo Abstract alla classe di livello superiore. Nell'esempio seguente viene mostrata una gerarchia che utilizza questa tecnica. La classe di livello superiore, TopInstance, è derivata da Instance e contrassegnata in modo esplicito con Abstract. Le classi derivate che non sono nodi foglia erediteranno correttamente questo attributo e saranno classi astratte di WMI come TopInstance. È necessario contrassegnare i nodi foglia come istanze concrete, pertanto questi avranno espliciti attributi Instance nella propria definizione di 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;
    }
}

Ereditarietà di istanze per classi non derivate da Instance

Se si utilizzano solo attributi per dichiarare classi di strumentazione di istanza, le gerarchie verranno definite in modo simile al metodo utilizzato per le classi di strumentazione di istanza derivate dalla classe di supporto System.Management.Instrumentation.Instance. Anche in questo caso la classe di strumentazione di istanza di primo livello deve essere contrassegnata con [InstrumentationClass(InstrumentationType.Abstract)], a meno che non esista una singola classe concreta di istanza di primo livello. I rami della gerarchia erediteranno questo attributo, pertanto non è necessario che dichiarino in maniera esplicita il proprio attributo InstrumentationClass. Di nuovo, i nodi foglia dovranno essere contrassegnati in modo esplicito come classi concrete di istanza di WMI e necessiteranno dell'attributo [InstrumentationClass(InstrumentationType.Instance)].

Nell'esempio seguente viene mostrata la stessa funzionalità dell'esempio precedente, ma viene utilizzato solo l'attributo InstrumentationClass anziché derivare la classe di livello superiore dalla classe di supporto 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);
    }
}

Vedere anche

Strumentazione di applicazioni .NET Framework tramite System.Management | Classi e mapping in CLI e WMI | Esposizione di eventi di gestione | Esposizione di dati di gestione | Registrazione dello schema per un'applicazione con strumentazione