无法通过温莎城堡从XML解析嵌套字典

时间:2018-07-04 16:14:45

标签: c# xml inversion-of-control castle-windsor

我必须通过Castle Windsor从XML配置文件中解析以下配置:

from abc import abstractmethod
from time import sleep
from threading import Thread, Event
from queue import Queue
import signal
import sys

class StoppableThread(Thread):

    def __init__(self):
        super().__init__()
        self.stopper = Event()
        self.queue = Queue()

    @abstractmethod
    def actual_job(self):
        pass

    def stop_running(self):
        self.stopper.set()

    def run(self):
        while not self.stopper.is_set():
            print(self.stopper.is_set())
            self.actual_job()
        self.queue.join()

class SomeObjectOne(StoppableThread):
    def __init__(self, name, some_object_two):
        super().__init__()
        self.name = name
        self.obj_two = some_object_two

    def actual_job(self):
        # print('{} is currently running'.format(self.name))
        input_string = 'some string'
        print('{} outputs {}'.format(self.name, input_string))
        self.obj_two.queue.put(input_string)
        sleep(2)

class SomeObjectTwo(StoppableThread):
    def __init__(self, name, some_object_three):
        super().__init__()
        self.name = name
        self.some_object_three = some_object_three

    def actual_job(self):
        # print('{} is currently running'.format(self.name))
        some_string = self.queue.get()
        inverted = some_string[::-1]
        print('{} outputs {}'.format(self.name , inverted))
        self.queue.task_done()
        self.some_object_three.queue.put(inverted)
        sleep(2)

class SomeObjectThree(StoppableThread):
    def __init__(self, name):
        super().__init__()
        self.name = name

    def actual_job(self):
        print('{} is currently running'.format(self.name))
        some_string = self.queue.get()
        print('{} outputs {}'.format(self.name ,some_string[::-1]))
        self.queue.task_done()
        sleep(2)

class ServiceExit(Exception):
    """
    Custom exception which is used to trigger the clean exit
    of all running threads and the main program.
    """
    pass

def service_shutdown(signum, frame):
    print('Caught signal %d' % signum)
    raise ServiceExit

signal.signal(signal.SIGTERM, service_shutdown)
signal.signal(signal.SIGINT, service_shutdown)

if __name__ == '__main__':
    thread_three = SomeObjectThree('SomeObjectThree')
    thread_two = SomeObjectTwo('SomeObjectTwo', thread_three)
    thread_one = SomeObjectOne('SomeObjectOne', thread_two)

    try:
        thread_three.start()
        thread_two.start()
        thread_one.start()

        # Keep the main thread running, otherwise signals are ignored.
        while True:
            sleep(0.5)

    except ServiceExit:
        print('Running service exit')
        thread_three.stop_running()
        thread_two.stop_running()
        thread_one.stop_running()
        thread_one.join()
        thread_two.join()
        thread_three.join()

从XML文件:

interface IMyConfiguration
{
    string Url { get; set; }
    string Token { get; set; }
    Dictionary <string, Dictionary <string, Guid>> Mapping { get; set; }
}

但是我得到的是将<?xml version="1.0" encoding="utf-8"?> <configuration> <components> <component id="myConfiguration" service="Application.IMyConfiguration, Application" type="Application.MyConfiguration, Application"> <parameters> <Url>example.com</Url> <Token>00000000-0000-0000-0000-000000000000</Token> <Mapping> <dictionary> <entry key="AA">${mapping_one}</entry> <entry key="BB">${mapping_two}</entry> </dictionary> </Mapping> </parameters> </component> <component id="mapping_one" service="System.Collections.Generic.IDictionary`2[[System.String, mscorlib],[System.Guid, mscorlib]]" type="System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Guid, mscorlib]]"> <parameters> <dictionary> <dictionary> <entry key="aa">00000000-0000-0000-0000-000000000000</entry> <entry key="bb">00000000-0000-0000-0000-000000000000</entry> <entry key="cc">00000000-0000-0000-0000-000000000000</entry> </dictionary> </dictionary> </parameters> </component> <component id="mapping_two" service="System.Collections.Generic.IDictionary`2[[System.String, mscorlib],[System.Guid, mscorlib]]" type="System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Guid, mscorlib]]"> <parameters> <dictionary> <dictionary> <entry key="aa">00000000-0000-0000-0000-000000000000</entry> <entry key="bb">00000000-0000-0000-0000-000000000000</entry> <entry key="cc">00000000-0000-0000-0000-000000000000</entry> </dictionary> </dictionary> </parameters> </component> </components> </configuration> 属性设置为Mapping。其他属性可以正常解析。

我在做什么错?如何正确执行?

我试图用Google搜索解决方案,但似乎没有人使用嵌套字典进行配置:)

到目前为止,我获得的最好的主意是使用列表而不是字典。


UPD。如果将nullmapping_one放在MyConfiguration组件中,则解析效果很好。

mapping_two

但是我希望嵌套字典是独立的组件。

1 个答案:

答案 0 :(得分:0)

我一直在家里使用xml linq进行此操作。我没有VS,所以希望语法正确

XDocument doc = XDocument("filename");

List<MyConfiguration> configs = doc.Descendants("parameters").Select(x => new MyConfiguration() {
   Url = (string)x.Descendants("Url").FirstOrDefault(),
   Token = (string)x.Descendants("Token").FirstOrDefault(),
   Mapping = x.Elements("Mapping").Select(m => m.Element("dictionary").Elements("entry")
             .GroupBy(y => (string)y.Attribute("key"), z => z.Descendants("entry")
                .GroupBy(a => (string)a.Attribute("key"), b => (string)b)
                .ToDictionary(a => a.Key, b => b.FirstOrDefault))
             .ToDictionary(y => y.Key, z => z.FirstOrDefault())
          .FirstOrDefault();

代码假定一个类