2 votes

Type générique vers mappage de valeur de configuration en C#

J'ai une interface pour contenir les informations de configuration de connexion pour l'accès au service web :

public interface IServiceConnectionConfiguration
{
    string Username { get; }
    string Password { get; }
    string ChannelEndpointUrl { get; }
    string MediaEndpointUrl { get; }
    string PlayerlEndpointUrl { get; }
    string PlaylistEndpointUrl { get; }
}

J'ai une classe fabrique qui renvoie l'instance de service spécifique au type de service demandé.

public static class ServiceClientFactory
{
    public static void Configure(IServiceConnectionConfiguration config)
    {
        _config = config;
    }
    public static T GetService() where T : class, IServiceClient
    {
    }
}

La fabrique est appelée comme

Channel channelService   = factory.GetService();

Ce que j'essaie de comprendre, c'est une façon élégante pour le code de la fabrique de résoudre les URL de point de terminaison pour les types passés en fonction de l'objet de configuration passé lors de l'initialisation. Par exemple, si le paramètre de type passé est "channel", il devrait prendre le "ChannelEndpointUrl" lors de la construction du "ChannelService".

J'ai pensé à utiliser des attributs sur la classe de configuration pour décorer les URLs de point de terminaison avec le type de service auquel ils correspondent, mais cela semble être une mauvaise conception.

Des idées ?

3voto

Pablo Romeo Points 5713

Eh bien, une manière de l'aborder serait d'avoir la Fabrique avoir un Dictionnaire static privé contenant votre logique d'initialisation, indexée par "Type". Similaire à un modèle de stratégie.

par exemple:

public static class FactoryDeClientDeService
{
    private static IConfigurationDeConnexionDeService _config;
    private static readonly Dictionary> Initializers = new Dictionary>();

    static FactoryDeClientDeService()
    {
        Initializers.Add(typeof(Canal), () =>
                                           {
                                               return //créer le client de service basé sur le point de terminaison
                                           });
    }

    public static void Configurer(IConfigurationDeConnexionDeService config)
    {
        _config = config;
    }

    public static T ObtenirService() where T : class, IClientDeService
    {
        return (T)Initializers[typeof (T)]();
    }
}

MODIFIER: Maintenant, comme vous l'avez mentionné, vous ne pouvez pas instancier explicitement dans votre fabrique car vous provoqueriez une référence circulaire, peut-être pouvez-vous imposer une contrainte new(), et construire l'instance dans la méthode ObtenirService, et utiliser le dictionnaire uniquement pour la configuration du point de terminaison, comme ceci:

public static class FactoryDeClientDeService
{
    private static IConfigurationDeConnexionDeService _config;
    private static readonly Dictionary> Initializers = new Dictionary>();

    static FactoryDeClientDeService()
    {
        Initializers.Add(typeof(Canal), t =>
                                          {
                                              t.Url = _config.UrlDePointDeTerminaisonDeCanal;
                                              //configurer t en utilisant le point de terminaison approprié
                                          });
    }

    public static void Configurer(IConfigurationDeConnexionDeService config)
    {
        _config = config;
    }

    public static T ObtenirService() where T : class, IClientDeService, new()
    {
        var service = new T();
        Initializers[typeof(T)](service);
        return service;
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X