迭代对象列表,实例化,并在每个对象上调用方法,而不显式地创建所有对象

本文关键字:对象 创建 方法 实例化 列表 迭代 调用 | 更新日期: 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;
}