ServiceProvider,缓存等,不需要强制转换 [英] ServiceProvider, cache etc. done with generics without cast

查看:83
本文介绍了ServiceProvider,缓存等,不需要强制转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在谈论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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆