2

Webサービスアクセス用の接続構成情報を保持するためのインターフェイスがあります。

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

要求されたサービスのタイプに固有のサービスインスタンスを返すファクトリクラスがあります。

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

工場はとして呼ばれます

Channel channelService   = factory.GetService<Channel>();

私が理解しようとしているのは、初期化中に渡された構成オブジェクトに基づいて、渡された型自体のエンドポイントURLをファクトリコードが解決するための洗練された方法です。例えば。渡されるtypeパラメーターがchannelの場合、ChannelServiceの構築中にChannelEndpointUrlを取得する必要があります。

configクラスの属性を使用して、エンドポイントURLをそれらが対応するサービスタイプで装飾することを考えましたが、それは悪い設計のようです。

何か案は。

4

1 に答える 1

3

これにアプローチする 1 つの方法は、Factory に、「タイプ」でインデックス付けされた初期化ロジックを含むプライベートな静的辞書を持たせることです。戦略パターンに似ています。

例えば:

public static class ServiceClientFactory
{
    private static IServiceConnectionConfiguration _config;
    private static readonly Dictionary<Type, Func<IServiceClient>> Initializers = new Dictionary<Type, Func<IServiceClient>>();

    static ServiceClientFactory()
    {
        Initializers.Add(typeof(Channel), () =>
                                               {
                                                   return //create the service client based on the endpoint
                                               });
    }

    public static void Configure(IServiceConnectionConfiguration config)
    {
        _config = config;
    }

    public static T GetService<T>() where T : class, IServiceClient
    {
        return (T)Initializers[typeof (T)]();
    }
}

EDIT:あなたが言及したように、循環参照を引き起こすため、ファクトリで明示的にインスタンス化することはできません.new()制約を強制し、GetServiceメソッドでインスタンスを構築し、エンドポイントの辞書のみを使用できます次のような構成:

public static class ServiceClientFactory
{
    private static IServiceConnectionConfiguration _config;
    private static readonly Dictionary<Type, Action<IServiceClient>> Initializers = new Dictionary<Type, Action<IServiceClient>>();

    static ServiceClientFactory()
    {
        Initializers.Add(typeof(Channel), t =>
                                              {
                                                  t.Url = _config.ChannelEndpointUrl;
                                                  //configure t using the appropriate endpoint
                                              });
    }

    public static void Configure(IServiceConnectionConfiguration config)
    {
        _config = config;
    }

    public static T GetService<T>() where T : class, IServiceClient, new()
    {
        var service = new T();
        Initializers[typeof(T)](service);
        return service;
    }
}
于 2012-06-01T05:43:16.670 に答える