Moyens de maintenir le code de configuration de la logique de code à l'aide de l'Injection de Dépendance
Comment peut garder tous les fichier de configuration de code de ma logique de code à l'aide de Paramètres (ApplicationSettingsBase) et l'Injection de Dépendance?
Avec la configuration que je veux dire un client fichier de configuration spécifique.
Dois-je vraiment injecter une classe de configuration à chaque fois que j'en ai besoin ou est-il un autre modèle?
Il serait bien d'obtenir un exemple de code!
Échantillons:
Configuration Statique:
public static class StaticConfiguration
{
public static bool ShouldApplySpecialLogic { get; set; }
public static string SupportedFileMask { get; set; }
}
public class ConsumerOfStaticConfiguration
{
public void Process()
{
if (StaticConfiguration.ShouldApplySpecialLogic)
{
var strings = StaticConfiguration.SupportedFileMask.Split(',');
foreach (var @string in strings)
{
}
}
}
}
Non statique de la Configuration:
public interface IConfiguration
{
bool ShouldApplySpecialLogic { get; set; }
string SupportedFileMask { get; set; }
}
public class Configuration : IConfiguration
{
public bool ShouldApplySpecialLogic { get; set; }
public string SupportedFileMask { get; set; }
}
public class Consumer
{
private readonly IConfiguration _configuration;
public Consumer(IConfiguration configuration)
{
_configuration = configuration;
}
public void Process()
{
if (_configuration.ShouldApplySpecialLogic)
{
var strings = _configuration.SupportedFileMask.Split(',');
foreach (var @string in strings)
{
}
}
}
}
Contexte statique non statique de la configuration:
public static class Context
{
public static IConfiguration Configuration { get; set; }
}
public class ConsumerOfStaticContext
{
public void Process()
{
if (Context.Configuration.ShouldApplySpecialLogic)
{
var strings = Context.Configuration.SupportedFileMask.Split(',');
foreach (var @string in strings)
{
}
}
}
}
- ce que vous voulez, c'est une Inversion de Contrôle Conteneur
- ce que je veux obtenir est une explication de la séparant de la logique de code de configuration en utilisant une inversion de contrôle conteneur.
- J'ai écrit un billet de blog expliquant comment et pourquoi nous utilisons StructureMap pour garder notre configuration distincte de notre logique: lostechies.com/joshuaflanagan/2009/07/13/... La fonctionnalité décrite dans ce post est maintenant disponible dans le FubuCore bibliothèque utilitaire (vous pouvez l'obtenir via nuget): github.com/DarthFubuMVC/fubucore/tree/master/src/FubuCore/...
Vous devez vous connecter pour publier un commentaire.
Le plus important à comprendre, c'est que la configuration n'est qu'une parmi plusieurs sources de valeurs qui animent votre comportement de l'application.
La deuxième option (non statique configuration) est meilleure car elle vous permet de complètement découpler la consommation de la source des valeurs de configuration. Cependant, l'interface n'est pas nécessaire, que les paramètres de configuration sont normalement mieux modélisé comme des Objets de Valeur de.
Si vous voulez continuer à lire les valeurs d'un fichier de configuration, vous pouvez le faire à partir de l'application La Composition De La Racine. Avec StructureMap, il pourrait ressemble à quelque chose comme ceci:
Les classes de Configuration de réduire cohension et augmentation de couplage dans les consommateurs. C'est parce qu'il peut y avoir de nombreux paramètres qui ne sont pas liées à un ou deux nécessaires à votre classe, mais pour répondre à la dépendance, de votre mise en œuvre de
IConfiguration
doit fournir des valeurs pour tous les accesseurs, même les non pertinents.Il aussi des couples de votre classe à l'infrastructure de la connaissance: les détails comme les "ces valeurs sont configurés ensemble" saigner de la configuration de l'application et à vos cours, une augmentation de la superficie affectée par les changements liés systèmes.
Le moins complexe, plus souple afin de partager les valeurs de configuration consiste à utiliser constructeur injection des valeurs elles-mêmes, de l'extériorisation des problèmes d'infrastructure. Cependant, dans un commentaire sur une autre réponse, vous indiquez que vous avez peur d'avoir beaucoup de paramètres du constructeur, qui est une préoccupation valable.
Le point clé de la reconnaître, c'est qu'il n'y a pas de différence entre les primitifs et des dépendances complexes. Si vous dépendez d'un entier ou d'une interface, ils sont tous les deux des choses que vous ne sais pas et doit être dit. De ce point de vue,
IConfiguration
sens autant que deIDependencies
. Les grands constructeurs indiquent une classe a trop de responsabilité, indépendamment de savoir si les paramètres sont primitives ou complexe.Envisager un traitement
int
,string
etbool
comme vous le feriez de toute autre dépendance. Elle permettra de rendre vos cours plus propre, plus ciblée, plus résistants au changement, et plus facile de test de l'unité.IConfiguration
mais juste leurs dépendances. Vous pouvez être amené un jour à avoir deux instances d'une classe configuré de manière différente. par exemple, "Comment les résultats diffèrent si l'on utilise la co-confabulator algorithme préférée par certaines installations au lieu de l'inverse-hindlebrook préféré par les autres?"IConfiguration
type peut réduire le nombre de paramètres du constructeur, mais il ne réduit pas la complexité, qui est le vrai danger derrière constructeur de ballonnement.Foo
seuls besoins de la valeur de A, puis le regroupement avec inutilisée, sans rapport avec les valeurs de B, C, et D augmente la complexité et le couplage avec aucun avantage àFoo
. Il vient de fuites de l'infrastructure de la connaissance dansFoo
.IServerContext
est beaucoup plus expressive queIConfiguration
. Le groupement doit favorable à l'intention de plus de mécanisme.#typedef
mais nous C# les gens n'obtiennent pas de cette option. J'ai créé un package NuGet appelé LikeType qui est similaire à la définition de type en C++ et il est facile d'éviter Primitive Obsession.Une façon consiste à injecter une interface de configuration comme vous le poste. Voici quelques autres façons.
Exposer un Setter
Dans la composition de la racine, vous pouvez lire un fichier de configuration ou les coder en dur. Autofac exemple:
C'est probablement seulement recommandé si vous avez un bon
Constructeur Injection
Dans la composition de la racine:
Dans mes applications, je ne ce que vous avez fait ci-dessus avec le Cio. C'est-à-dire, le fait d'avoir mon conteneur IoC (StructureMap aussi) injecter une
IApplicationSettings
dans mes classes.Par exemple, dans un ASP.NET MVC3 projet, il peut ressembler à:
Ma mise en œuvre de
IApplicationSettings
tire la plupart des choses de l'application de la.config
fichier et a quelques valeurs codées en dur, il y a l'.Mon exemple n'est pas logique de contrôle de flux (comme ton exemple), mais il aurait pu tout de même si elle l'était.
L'autre façon de faire serait de faire un service de localisation de type schéma, où vous demandez à votre conteneur d'Injection de Dépendance pour vous obtenir une instance de la classe de configuration à la volée. Service de Localisation est considéré comme un anti-modèle général, mais peut-être encore de l'utiliser pour vous.