C # несколько файлов настроек с одинаковым интерфейсом - PullRequest
0 голосов
/ 15 декабря 2009

Я пытаюсь создать программу с двумя (или более) дискретными наборами настроек, которые соответствуют одному и тому же интерфейсу. В частности, я хотел бы сделать что-то вроде следующего, используя настройки, сгенерированные дизайнером:

IMySettings settings = Properties.A;
Console.WriteLine(settings.Greeting);
settings = Properties.B;
Console.WriteLine(settings.Greeting);

Это было бы тривиально с интерфейсами Go, потому что любой класс (?), Который предоставляет методы, может быть назначен, но как я могу реализовать это в C # с его строгими правилами реализации интерфейса?

Примечание: C # /. NET 2.0

Ответы [ 5 ]

2 голосов
/ 15 декабря 2009

Класс Properties.Settings, сгенерированный в VS, не позволит вам сделать это. Попробуйте определить простой класс DTO и пометить его с помощью XmlAttribute, чтобы вы могли легко десериализовать его.

1 голос
/ 16 декабря 2009

Я не уверен, что вы можете делать то, что вы, с помощью настроек, сгенерированных дизайнером, но я не часто их использую, поэтому могу ошибаться. Однако есть еще один способ сделать это: создать собственный ConfigurationSection .

Вот пример:

public class MyProperties : ConfigurationSection {
    [ConfigurationProperty("A")]
    public MySettings A
    {
        get { return (MySettings )this["A"]; }
        set { this["A"] = value; }
    }

    [ConfigurationProperty("B")]
    public MySettings B
    {
        get { return (MySettings )this["B"]; }
        set { this["B"] = value; }
    }
}

public class MySettings : ConfigurationElement {
    [ConfigurationProperty("greeting")]
    public string Greeting
    {
        get { return (string )this["greeting"]; }
        set { this["greeting"] = value; }
    }
}

И тогда вашему app.config / web.config необходимо следующее:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="mySettings" type="Namespace.MyProperties, Assembly"/>
    </configSections>
    <mySettings>
        <A greeting="Hello from A!" />
        <B greeting="Hello from B" />
    </mySettings>
</configuration>

В этом могут быть опечатки, но общая идея есть. Надеюсь, это поможет.

1 голос
/ 15 декабря 2009

Я не уверен, что вы спрашиваете, как реализовать интерфейс в C #.

Если это так, просто сделайте что-то вроде:

Public Interface IMySettings {
   Public string Greeting {get;set;}
}

Тогда просто попросите ваши "A" и "B" реализовать этот интерфейс и вернуть желаемое приветствие. В результате ваш класс Properties будет реализовывать IMySettings, а не прямой класс:

Public class Properties {
   public IMySettings A {get;set;}
   public IMySettings B {get;set;}
}

Поэтому вместо использования «MySettings» ваш код будет выглядеть так:

IMySettings settings = Properties.A;
1 голос
/ 15 декабря 2009

Вы также можете использовать интерфейсы в C #.

Однако вам придется написать класс фасада, если вы все еще хотите использовать сгенерированные дизайнером настройки.

0 голосов
/ 02 сентября 2012

Вы можете использовать собственный генератор кода для вставки вашего интерфейса в сгенерированный код (используя метод здесь: http://brannockdevice.blogspot.co.uk/2006_01_22_archive.html). Это очень просто и очень аккуратно, но проблема в том, что если вы работаете в команде, тогда им всем потребуется обновить реестр, чтобы создать решение.

Другой вариант и, возможно, самый близкий ответ на ваш исходный вопрос, это создать класс универсальных свойств и затем заполнить его, возможно, с помощью явного приведения -

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace ConsoleApplication6
{

    // use this class if you plan to add lots more settings files in future (low maintenance)
    class GenericProps1 
    {
        public string TestString { get; private set; }

        // single cast for all settings files
        public static explicit operator GenericProps1(ApplicationSettingsBase props)
        {
            return new GenericProps1() { TestString = props.Properties["TestString"].DefaultValue.ToString() };
        }
    }

    // use this class if you do NOT plan to add lots more settings files in future (nicer code)
    class GenericProps2 
    {
        public string TestString { get; private set; }

        // cast needed for settings1 file
        public static explicit operator GenericProps2(Properties.Settings1 props)
        {
            return new GenericProps2() { TestString = props.TestString };
        }

        // cast needed for settings 2 file
        public static explicit operator GenericProps2(Properties.Settings2 props)
        {
            return new GenericProps2() { TestString = props.TestString };
        }

        // cast for settings 3,4,5 files go here...
    }


    class Program
    {
        // usage
        static void Main(string[] args)
        {
            GenericProps1 gProps1_1 = (GenericProps1)Properties.Settings1.Default;
            GenericProps1 gProps1_2 = (GenericProps1)Properties.Settings2.Default;
            //or
            GenericProps2 gProps2_1 = (GenericProps2)Properties.Settings1.Default;
            GenericProps2 gProps2_2 = (GenericProps2)Properties.Settings2.Default;
        }
    }

}
...