neděle 25. září 2016

Konfigurace metody

Postupy zmíněné v článcích o konfiguračních souborech - zde a zde - jsem využil a udělal jsem si knihovnu pro vytvoření objektu a jeho naplnění hodnotami z konfigurace. Nicméně při sepisování požadavků jsem narazil na problém, že předání všech možných kombinací nastavení do objektu, respektive metody) by vedlo k mnoha přetížením dané  metody a celkově obtížnější orientaci v kódu (používám Code Analysis a tedy nejde jen tak použít nepovinné parametry, metoda se musí přetížit). 
Konkrétně jsem chtěl nastavit:


  • zdroj konfiguračních dat, například jestli budou z konfiguračního souboru, ze Service Fabric konfigurace apod
  • které vlastnosti nenastavovat,
  • a které naopak nastavit
  • jak je mapovat na určitý klíč v konfiguraci
  • jak nastavit společnou předponu v názvu klíče

Nakonec jsem použil něco, co si pracovně nazývám Fluent settings.   Pro výše uvedené požadavky jsem si definoval toto rozhraní:

public interface IBindingRule<TElement>
{
    IBindingRule<TElementExclude<TProperty>(Expression<Func<TElementTProperty>> propertyLambda);
 
    IBindingRule<TElementSetOnly<TProperty>(Expression<Func<TElementTProperty>> propertyLambda);
 
    IBindingRule<TElementMapTo<TProperty>(
        Expression<Func<TElementTProperty>> propertyLambda,
        string sourceName);

    IBindingRule<TElementPrefix(string name);
 
    IBindingRule<TElementFrom(IValueProvider source);
}

a metodu pro vytvoření objektu a jeho naplnění konfiguračními daty jsem upravil takto:

public delegate void ConfigurationBindingSettings<TElement>(IBindingRule<TElementelement);
 
public static TElement CreateAndSetInstance<TElement>(ConfigurationBindingSettings<TElementsettings)

Tato metoda si po spuštění vytvoří instanci objektu, který rozhraní implementuje a vykoná všechny určené akce (voláním settings(instance objektu)). Ve výsledku to pak vše dohromady umožní tento zápis v kódu, který vytvoří instanci třídy ConnectionPolicy a  naplní ji konfiguračními hodnotami mimo třech určených vlastnosti:

var documentDbConnectionPolicy = ConfigurationActivator.CreateAndSetInstance<ConnectionPolicy>(
    settings => settings
    .From(From.ServiceFabricConfigurationPackage("Config""Policy"))
    .Prefix("DocumentDb.ConnectionPolicy")
    .Exclude(p => p.EnableEndpointDiscovery)
    .Exclude(p => p.MaxConnectionLimit)
    .Exclude(p => p.UserAgentSuffix));

Ten delegát je vlastně jen náhradou zápisu Action<IBindingRule<TElement>>, který nemá CA rád.
Díky výše uvedenému způsobu není nutné definovat metodu CreateAndSetInstance několikrát s různými vstupními parametry.

Žádné komentáře:

Okomentovat