开发者

C# multiple settings files with same interface

开发者 https://www.devze.com 2022-12-13 22:34 出处:网络
I\'m trying to create a program with two (or more) discrete sets of settings, that both conform to the same interface.Particularly I\'d like to do something like the following, using designer generate

I'm trying to create a program with two (or more) discrete sets of settings, that both conform to the same interface. Particularly I'd like to do something like the following, using designer generated settings:

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

This would be trivial with Go's interfaces because any class(?) that provides the methods can be assigned, but how can I implement this in C#, with its strict interface开发者_开发技巧 implementation rules?

Note: C#/.NET 2.0


The Properties.Settings class generated in VS is not going to let you do this. Consider defining a simple DTO class and marking it up with XmlAttribute so that you can easily deserialize it.


You can use interfaces in C#, too.

However, you'll have to write a facade class if you still want to use the designer-generated settings.


I'm not sure if what you're asking is how to implement an interface in C#.

If it is, just make something like:

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

Then just have your "A" and "B" implement this interface and returns your desired greeting. As a result your Properties class will implement IMySettings as opposed to a straight class:

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

So instead of using "MySettings", your code would look like so:

IMySettings settings = Properties.A;


I'm not sure if you can do what you through the designer generated settings, but I don't use them often so I could be wrong. However, there is another way you could do this: creating your own ConfigurationSection.

Here is an example:

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; }
    }
}

And then your app.config/web.config needs the following:

<?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>

There may be typos in that but the overall idea is there. Hope that helps.


You could use a custom code generator to insert your interface into the generated code (using the method here: http://brannockdevice.blogspot.co.uk/2006_01_22_archive.html). It's very easy and very tidy, but the problem is, if you are working in a team, then they would all need to update their registry to build the solution.

Another option, and probably the closest answer to your original question, is to create a generic properties class and then populate, possibly via an explicit cast -

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;
        }
    }

}
0

精彩评论

暂无评论...
验证码 换一张
取 消