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,但这似乎是一个糟糕的设计。
任何想法。
嗯,一种方法是让工厂有一个私有的静态字典,其中包含你的初始化逻辑,按"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;
}
}