2010-12-14 32 views
0

J'ai implémenté (en utilisant l'espace de noms System.Configuration) et configuré suivant la structure App.config:Lire App.Config LINQ

<bot> 
    <strategies> 
     <add name="TestStrategy" type="Bot.Strategy.Test" > 
      <indicators> 
       <add name="Foo" type="Bot.Indicators.Foo, Bot" /> 
       <add name="Bar" type="Bot.Indicators.Bar, Bot" /> 
      </indicators> 
      <orders> 
       <add id="123" amount="0.1" /> 
      </orders> 
     </add> 
    </strategies> 
</bot> 

pour les classes suivantes:

class TestStrategy : IStrategy 
{ 
    public TestStrategy(IEnumerable<IIndicator> indicators, IEnumerable<Order> orders) { } 
} 

interface IIndicator { } 

class Order 
{ 
    public int ID { get; set; } 
    public double Amount { get; set; } 
} 

Alors, comment puis-je lire mon App.config pour instancier IEnumerable<IStrategy> en appelant le constructeur de chacun avec IEnumerable<IIndicator> et IEnumerable<Order> en utilisant LINQ?

J'ai déjà suivant:

var section = ((BotSection)ConfigurationManager.GetSection("bot")); 
return from strategy in section.Strategies 
     let strategyType = Type.GetType(strategy.Type) 
     where !strategyType.IsInterface && !strategyType.IsAbstract && typeof(IStrategy).IsAssignableFrom(strategyType) 
     select (IStrategy)Activator.CreateInstance(strategyType, ?); 
+1

Personnellement, je ne voudrais pas ignorer les types qui aren 't concret (comme vous le faites dans la clause 'where'), mais je voudrais lancer une exception spécifique décrivant le problème réel, ou laisser le' Activator' jeter cette exception pour vous. – Steven

Répondre

1

Si votre BotSection est correctement défini, vous pouvez le faire (notez les requêtes sous):

return 
    from strategy in section.Strategies 
    let strategyType = Type.GetType(strategy.Type) 
    where !strategyType.IsInterface && !strategyType.IsAbstract 
     && typeof(IStrategy).IsAssignableFrom(strategyType) 
    let indicators = (
     from indicator in strategy.Indicators 
     let indicatorType = Type.GetType(indicator.Type) 
     select (IIndicator)Activator.CreateInstance(indicatorType)) 
    let orders = (
     from order in strategy.Orders 
     let id = order.Id 
     select new Order { Id = order.Id, Amount = order.Amount }) 
    select (IStrategy)Activator.CreateInstance(strategyType, indicators, orders); 
+0

Il n'y a aucun moyen d'éviter d'utiliser des cahiers imbriqués, non? – abatishchev

+0

Vous pouvez refactoriser la création de 'strategyType' et les sous-requêtes à une méthode et faire' select CreateStrategy (strategy) ', mais cela ne supprime pas vraiment les requêtes imbriquées. Je ne connais pas d'autre moyen. – Steven