ServiceProvider,缓存等,不需要强制转换 [英] ServiceProvider, cache etc. done with generics without cast
问题描述
我在谈论c# 3.5 3.0。
当缓存或ServiceProvider只能有一个整个应用程序的实例时,我知道该怎么做。在这种情况下,ServiceProvider可能如下所示:
I'm talking about c# 3.5 3.0.
I know how to do it when cache or ServiceProvider can have only one instance for the whole application. In this case ServiceProvider can look like this
public static class Service<T>
{
public static T Value {get; set;}
}
可用于像这样的不同类型:
and can be used for different types like this:
Service<IDbConnection>.Value = new SqlConnection("...");
Service<IDesigner>.Value = ...;
//...
IDbCommand cmd = Service<IDbConnection>.Value.CreateCommand();
静态缓存也很容易:
Static cache is also easy:
public static class Cache<T>
{
private static Dictionary<int, T> cache = new Dictionary<int, T>();
public static void Add(int key, T value)
{
cache.Add(key, value);
}
public static T Find(int key)
{
return cache[key];
}
}
可以像这样使用:
Cache<string>.Add(1, "test");
Cache<DateTime>.Add(2, DateTime.Now);
//...
string found = Cache<string>.Find(1);
我的问题是:我怎么能创建类似的缓存或服务提供者,当我想要有两个或更多不同的每个实例时。这里是示例代码,我想如何使用服务提供者:
My question is: how can I create similiar cache or service provider when I want to have 2 or more different instances of each. Here is example code, how I want to use service provider:
ServiceProvider provider = new ServiceProvider();
provider.Add<IDbConnection>(new SqlConnection("..."));
provider.Add<IDesigner>(...);
//...
ServiceProvider provider1 = new ServiceProvider();
provider1.Add<IDbConnection>(new SqlConnection("..."));
//...
//...
IDbCommand cmd1 = provider.GetService<IDbConnection>().CreateCommand();
IDbCommand cmd2 = provider1.GetService<IDbConnection>().CreateCommand();
我头脑中唯一的实现是使用强制转换,我希望避免。
The only implementation that I have in my head is using casting which I want to avoid.
public class ServiceProvider
{
private Dictionary<Type, object> services = new Dictionary<Type, object>();
public void Add<T>(T value)
{
services.Add(typeof(T), value);
}
public T GetService<T>()
{
return (T) services[typeof (T)];
}
}
推荐答案
你是否特别迫切希望避免施法?是的,它感觉不安全 - 但基本上可以保证它不会成为ServiceProvider中的问题,而且客户端也没有进行任何投射。
Why are you particularly desperate to avoid casting? Yes, it feels "unsafe" - but you can basically guarantee that it's not going to be an issue in ServiceProvider, and the clients aren't doing any casting.
是一个相当普遍的问题,但我不相信在.NET泛型中有很好的解决方案 - 它是一种基本无法表达的类型关系。
This is a reasonably common problem, but I don't believe there's any nice solution to it within .NET generics - it's a type relationship which can't be expressed, basically.
编辑:我现在博客关于这一点,并将行为封装在一个类型中。如果它能让你的事情保持清洁,请随时取用该代码。
I've now blogged about this and encapsulated the behaviour in a type. Feel free to take that code if it keeps things cleaner for you.
这篇关于ServiceProvider,缓存等,不需要强制转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!