迭代对象列表,实例化,并在每个对象上调用方法,而不显式地创建所有对象
本文关键字:对象 创建 方法 实例化 列表 迭代 调用 | 更新日期: 2023-09-27 18:08:21
假设我在WCF服务中有一堆类要公开给消费者。该列表在名为clsServiceEnumertion的方法中枚举。ListOfServices(返回WCF服务中的Dictionary(string, Boolean))。可用包装类的列表存储在此服务枚举中的枚举中,它们的枚举与类名相同(例如clsEmailWrapper、clsPDFGenerator等)。通过这种方式,我们可以将可重用对象作为服务公开给多个内部托管的网站(和内部软件),而无需重写大量代码、复制代码、单点更新等。
在任何给定的时间,这些包装类中的任何一个都可能不可用(由于维护、错误、中断等原因)。这由用户在配置应用程序中控制。我们也无法提前知道将有多少服务,或者它们将被称为什么(一年后可能会有,比如说,50个)。可用的服务和是否启用的服务存储在xml文件中,并以Dictionary(string, boolean)的形式在系统中传播。
听起来像是利用布尔值的迭代器的主要候选对象。问题:我只有对服务类的字符串引用,而这些引用恰好与有用但描述性命名的捆绑类相同。
我知道什么是反射和激活,但我的脑子里并没有正确地把它们放在一起。谁能帮帮我如何遍历这本字典,得到类的名称作为字符串如果布尔是真的,创建一个对象的类型和调用test方法将存在于所有包装类(测试方法是确保服务可以运行和将返回一个布尔,而迭代器本身将类的名称,结果存储在字典(字符串、布尔值))。
除了实际的迭代器,我已经写好了所有的东西。
public Dictionary<string, Boolean> TestEnabledServices(Dictionary<string, Boolean> listOfEnabledServices)
{
Dictionary<string, Boolean> resultSet = new Dictionary<string, bool>();
foreach (KeyValuePair<string, Boolean> pair in listOfEnabledServices)
{
if (pair.Value)
{
Boolean retVal = false;
//TODO: actual test here
retVal = true ? true : false; //the result of the test...
resultSet.Add(pair.Key, retVal);
}//end if
}//end foreach
return resultSet;
}//end TestEnabledService
我想这就是你想要的
Dictionary<string, bool> GetEnabledAndTestedServices(Dictionary<string, bool> input)
{
var testedServices = new Dictionary<string, bool>();
foreach(var kvp in input)
{
if(!kvp.Value) //disabled
continue;
var type = Type.GetType(kvp.Key);
if(type == null)
throw new Exception("This service does not exist!");
var instance = Activator.CreateInstance(type);
// if the Test() method is part of an interface
// public interface ITestableService { bool Test() }
// and it's implemented by all services we can do this:
var service = instance as ITestableService;
if(service != null)
{
if(service.Test())
testedServices.Add(kvp.Key, true);
}
else //Otherwise we call it via reflection, you could also do dynamic
{
var testMethod = type.GetMethod("Test");
if(testMethod == null)
throw new Exception("The service is not testable");
var testResult = testMethod.Invoke(instance, null) as bool?;
if(testResult.HasValue && testResult.Value)
testedServices.Add(kvp.Key, true);
}
}
return testedServices;
}