Come incapsulare le variabili "globali" in C #? /la migliore pratica

9

In C # qual è la migliore pratica per incapsulare le variabili che devo usare in più metodi? È giusto dichiararli semplicemente in cima alla mia classe sopra i due metodi?

Inoltre, se utilizzo le impostazioni dell'app dal mio file di configurazione dovrei usare un getter? così ...

private string mySetting{ get { return WebConfigurationManager.AppSettings["mySetting"]; } }

Che buone pratiche è?

    
posta user1944367 19.04.2013 - 01:15
fonte

2 risposte

5

Non è solo OK. Secondo il libro Clean Code, in realtà è una pratica molto buona, e lo zio Bob lo incoraggia davvero. Una variabile utilizzata da molti metodi potrebbe mostrare un alto grado di coesione tra i metodi. Inoltre, un alto grado di variabili oggetto potrebbe anche suggerire che detta classe dovrebbe essere divisa in due, quindi dichiararli come variabili oggetto potrebbe aiutarti a scoprire candidati di classe nascosti.

Le variabili a livello di oggetto non sono variabili globali, quindi non aver paura di usarle se devono essere condivise con vari metodi.

    
risposta data 19.04.2013 - 05:25
fonte
4

Incapsulare le tue impostazioni in modo costante è una grande idea.

Quello che faccio è creare una classe di impostazioni sia statiche globali che multiple, che poi gestirò con l'iniezione delle dipendenze. Quindi carico tutte le impostazioni dalla configurazione a quella classe all'avvio.

Ho anche scritto una piccola libreria che usa il reflection per renderlo ancora più semplice.

Una volta che le mie impostazioni sono nel mio file di configurazione

<?xml version="1.0" encoding="utf-8" ?>
<configuration>   
    <appSettings>
        <add key="Domain" value="example.com" />
        <add key="PagingSize" value="30" />
        <add key="Invalid.C#.Identifier" value="test" />
    </appSettings>
</configuration>

Creo una classe statica o di istanza in base alle mie esigenze. Per le applicazioni semplici con solo alcune impostazioni, una classe statica va bene.

private static class Settings
{
    public string Domain { get; set; }

    public int PagingSize { get; set; }

    [Named("Invalid.C#.Identifier")]
    public string ICID { get; set; }

}

Quindi, usando la mia chiamata alla biblioteca, Inflate.Static o Inflate.Instance e la cosa interessante è che posso usare qualsiasi sorgente di valori chiave.

using Fire.Configuration;

Inflate.Static( typeof(Settings), x => ConfigurationManager.AppSettings[x] );

Tutto il codice per questo è in GitHub all'indirizzo link

Esiste persino un pacchetto nuget:

PM> Install-Package Enexure.Fire.Configuration

Codice per riferimento:

using System;
using System.Linq;
using System.Reflection;
using Fire.Extensions;

namespace Fire.Configuration
{
    public static class Inflate
    {
        public static void Static( Type type, Func<string, string> dictionary )
        {
            Fill( null, type, dictionary );
        }

        public static void Instance( object instance, Func<string, string> dictionary )
        {
            Fill( instance, instance.GetType(), dictionary );
        }


        private static void Fill( object instance, Type type, Func<string, string> dictionary ) 
        {

            PropertyInfo[] properties;
            if (instance == null) {

                // Static
                properties = type.GetProperties( BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly );
            } else {

                // Instance
                properties = type.GetProperties( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly );
            }

            // Get app settings and convert
            foreach (PropertyInfo property in properties) {
                var attributes = property.GetCustomAttributes( true );
                if (!attributes.Any( x => x is Ignore )) {

                    var named = attributes.FirstOrDefault( x => x is Named ) as Named;

                    var value = dictionary((named != null)? named.Name : property.Name);

                    object result;
                    if (ExtendConversion.ConvertTo(value, property.PropertyType, out result)) {
                        property.SetValue( instance, result, null );
                    }
                }
            }
        }
    }
}
    
risposta data 20.04.2013 - 04:47
fonte

Leggi altre domande sui tag