C# 中的泛型类型到配置值映射

本文关键字:配置 映射 泛型类型 | 更新日期: 2023-09-27 18:36:09

>我有一个用于保存 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。 例如。如果传递的类型参数是 channel,则在构造 ChannelService 时应采用 ChannelEndpointUrl。

我考虑过在 config 类上使用属性来使用它们对应的服务类型装饰端点 url,但这似乎是一个糟糕的设计。

任何想法。

C# 中的泛型类型到配置值映射

嗯,一种方法是让工厂有一个私有的静态字典,其中包含你的初始化逻辑,按"Type"索引。类似于策略模式。

例如:

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)]();
    }
}

编辑:现在,正如你提到的,你不能在你的工厂中显式实例化,因为你会导致循环引用,也许你可以强制一个新的()约束,并在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;
    }
}