Here is my situation. I am working with WMI in C#. Thankfully, I found MgmtClassGen.exe which generated all of the classes I need for now.
However, I have been going through the auto generated classes, and ripping out the common code to either a Utility class, or a base class. So far so good, got a lot of the code cleaned up. But I’ve hit a snag. Each class has several (about 8) static functions called GetInstances. Basically there are 2 overloads, and the other function are just providing default parameters.
I would like to put these function in the base class because they are identical across all the classes, except for 3 variables. Namely, the ClassName (like “MicrosoftDNS_Zone“) of the object, the Namespace (like “root\microsoftdns“) of the Object, and a ManagementScope object.
What I have done currently is this; Moved the 2 functions with code in them to the base class and added 3 parameters, for the 3 differences listed above. But this still requires 8 functions in each class that just call the base class with the ClassName, Namespace, and Scope parameters filled in.
- Is there any way to refactor this
code so that I don’t need the method
“wrappers” in each derived class? - Can I just declare the static
methods in the base class and
somehow get the ClassName, etc. from
the derived class? - Would reflection even work here?
Base Class:
namespace WMI
{
public abstract class Object : System.ComponentModel.Component
{
// ...
protected static WMI.ManagementTypeCollection GetInstances( string className, string namespaceName, ManagementScope statMgmtScope, ManagementScope mgmtScope, EnumerationOptions enumOptions, Func<ManagementObject,WMI.Object> del )
{
if( (mgmtScope == null) )
{
if( (statMgmtScope == null) )
{
mgmtScope = new System.Management.ManagementScope();
mgmtScope.Path.NamespacePath = namespaceName;
}
else
{
mgmtScope = statMgmtScope;
}
}
System.Management.ManagementPath pathObj = new System.Management.ManagementPath();
pathObj.ClassName = className;
pathObj.NamespacePath = namespaceName;
System.Management.ManagementClass clsObject = new System.Management.ManagementClass( mgmtScope, pathObj, null );
if( (enumOptions == null) )
{
enumOptions = new System.Management.EnumerationOptions();
enumOptions.EnsureLocatable = true;
}
return new WMI.ManagementTypeCollection( clsObject.GetInstances( enumOptions ), del );
}
protected static WMI.ManagementTypeCollection GetInstances( string className, string namespaceName, ManagementScope statMgmtScope, ManagementScope mgmtScope, string condition, String[] selectedProperties, Func<ManagementObject, WMI.Object> del )
{
if( (mgmtScope == null) )
{
if( (statMgmtScope == null) )
{
mgmtScope = new System.Management.ManagementScope();
mgmtScope.Path.NamespacePath = namespaceName;
}
else
{
mgmtScope = statMgmtScope;
}
}
System.Management.ManagementObjectSearcher ObjectSearcher = new System.Management.ManagementObjectSearcher( mgmtScope, new SelectQuery( className, condition, selectedProperties ) );
System.Management.EnumerationOptions enumOptions = new System.Management.EnumerationOptions();
enumOptions.EnsureLocatable = true;
ObjectSearcher.Options = enumOptions;
return new WMI.ManagementTypeCollection( ObjectSearcher.Get(), del );
}
}
}
Derived Class:
namespace WMI.MicrosoftDNS
{
public class AAAAType : WMI.Object
{
private static string CreatedWmiNamespace = "root\\microsoftdns";
private static string CreatedClassName = "MicrosoftDNS_AAAAType";
private static System.Management.ManagementScope statMgmtScope = null;
// ...
public static WMI.ManagementTypeCollection GetInstances()
{
return GetInstances( null, null, null );
}
public static WMI.ManagementTypeCollection GetInstances( string condition )
{
return GetInstances( null, condition, null );
}
public static WMI.ManagementTypeCollection GetInstances( System.String[] selectedProperties )
{
return GetInstances( null, null, selectedProperties );
}
public static WMI.ManagementTypeCollection GetInstances( string condition, System.String[] selectedProperties )
{
return GetInstances( null, condition, selectedProperties );
}
public static WMI.ManagementTypeCollection GetInstances( ManagementScope mgmtScope, EnumerationOptions enumOptions )
{
return WMI.Object.GetInstances( CreatedClassName, CreatedWmiNamespace, statMgmtScope, mgmtScope, enumOptions, mo => new AAAAType( mo ) );
}
public static WMI.ManagementTypeCollection GetInstances( ManagementScope mgmtScope, string condition )
{
return GetInstances( mgmtScope, condition, null );
}
public static WMI.ManagementTypeCollection GetInstances( ManagementScope mgmtScope, System.String[] selectedProperties )
{
return GetInstances( mgmtScope, null, selectedProperties );
}
public static WMI.ManagementTypeCollection GetInstances( ManagementScope mgmtScope, string condition, System.String[] selectedProperties )
{
return WMI.Object.GetInstances( CreatedClassName, CreatedWmiNamespace, statMgmtScope, mgmtScope, condition, selectedProperties, mo => new AAAAType( mo ) );
}
}
}
Why not move these eight common functions into a separate class as instance methods, and initialize the instance with the three parameters that vary by class. Then you could aggregate and expose the instance of that helper class on each of the derived types. Since the static methods can’t use any instance data, there’s no reason to duplicate them.
Here’s an example of what I mean: