这是我的情况。我正在使用C#中的WMI。值得庆幸的是,我发现MgmtClassGen.exe生成了我现在需要的所有类。
但是,我一直在浏览自动生成的类,并将公共代码转换为Utility类或基类。到目前为止一切都那么好,清理了很多代码。但我遇到了麻烦。每个类都有几个(大约8个)静态函数,称为GetInstances
。基本上有2个重载,而另一个函数只是提供默认参数。
我想将这些函数放在基类中,因为它们在所有类中是相同的,除了3个变量。即,对象的ClassName
(如“MicrosoftDNS_Zone
”),对象的Namespace
(如“root\microsoftdns
”)和ManagementScope
对象
我目前所做的是这个;将包含其中代码的2个函数移动到基类,并为上面列出的3个差异添加了3个参数。但是这仍然需要在每个类中使用8个函数来调用基类,并填充ClassName
,Namespace
和Scope
个参数。
基类:
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 );
}
}
}
派生类:
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 ) );
}
}
}
答案 0 :(得分:2)
为什么不将这八个常用函数作为实例方法移动到单独的类中,并使用因类而异的三个参数初始化实例。然后,您可以在每个派生类型上聚合并公开该帮助程序类的实例。由于静态方法不能使用任何实例数据,因此没有理由复制它们。
这是我的意思的一个例子:
public class WMIInstance
{
private readonly string CreatedWmiNamespace = "root\\microsoftdns";
private readonly string CreatedClassName = "MicrosoftDNS_AAAAType";
private readonly System.Management.ManagementScope statMgmtScope = null;
public WMIInstance( string namespace, string className, ManagementScope scope )
{ /*... initialize private members here... */
public WMI.ManagementTypeCollection GetInstances( System.String[] selectedProperties )
{ return WMI.Object.GetInstances( ... ); }
/* other overloads ... */
}
public class AAAAType : WMI.Object
{
private static string CreatedWmiNamespace = "root\\microsoftdns";
private static string CreatedClassName = "MicrosoftDNS_AAAAType";
private static System.Management.ManagementScope statMgmtScope = null;
private static readonly WMIInstances _instances = new WMIInstance( CreatedWmiNamespace, CreatedClassName, statMgmgtScope );
public static WMIInstances Getter { get { return _instances; } }
}
答案 1 :(得分:1)
它可能不是您的选择,但C#4.0支持optional arguments方法的默认值,这消除了在很多情况下需要多次重载的需要。例如:
public void ExampleMethod(int required, string optionalstr = "default string",
int optionalint = 10)
您可以使用ExampleMethod(1)
或ExampleMethod(1, 'Test', 9)
调用上述方法。
答案 2 :(得分:0)
也许是一家小工厂?
class Config { string ClassName; string Namespace; ManagementScope Scope; }
static class Factory {
public static readonly Dictionary<Type, Config> Configs = new ...;
static GetInstances(Type requestedType, ...) {
var config = Configs[requestedType];
// work with it...
}
}
class AAAAType {
static AAAAType{
Factory.Configs.Add(typeof(AAAAType), new Config{ ... });
}
}
它可能不是完美的代码,但我不想远离你的初始提案。此外,我不喜欢它,并建议重新设计你的想法,因为: