哪些IoC容器支持基于标识符返回特定对象?

时间:2011-02-11 17:25:50

标签: c# mvvm ioc-container

我刚开始尝试使用IoC容器。目前,我正在使用一个本土工厂来构建我的ViewModel,它有两种版本:singleton和id-based。换句话说,我的应用程序(按照定义)一次只有一个Room,因此只有一个RoomViewModel,但很多用户可以在那个房间,所以我需要很多UserViewModel。但是我想确保对于User with UserId =“johnsmith”的用户,只创建了一个UserViewModel,并且任何检索该UserViewModel的尝试都将返回相同的实例。

我不知道它是否有助于解释或混淆它们,但这是我目前使用的方法:

public ViewModelType GetViewModelByKey<ViewModelType, KeyType>(KeyType key) 
        where ViewModelType : AlantaViewModelBase, new()
    {
        IDictionary dictionary;
        var type = typeof(ViewModelType);
        if (!keyedViewModelDictionaries.TryGetValue(type, out dictionary))
        {
            dictionary = new Dictionary<KeyType, ViewModelType>();
            keyedViewModelDictionaries.Add(type, dictionary);
        }
        var viewModels = (Dictionary<KeyType, ViewModelType>)dictionary;
        ViewModelType vm;
        if (!viewModels.TryGetValue(key, out vm))
        {
            vm = new ViewModelType();
            viewModels.Add(key, vm);
            vm.Initialize(this);
        }
        return vm;
    }

这意味着这两个调用将返回单独的实例:

// Get VM for user.UserId="john";
var userVM1 = viewModelFactory.GetViewModelByKey<UserViewModel, string>("john");
// Get VM for user.UserId="suzie";
var userVM2 = viewModelFactory.GetViewModelByKey<UserViewModel, string>("suzie");

但是这些将返回相同的实例:

// Get the same VM for user.UserId="bob";
var userVM1 = viewModelFactory.GetViewModelByKey<UserViewModel, string>("bob");
var userVM2 = viewModelFactory.GetViewModelByKey<UserViewModel, string>("bob");

这样做的能力解决了许多数据绑定和同步问题,所以这不是我将轻易放弃的模式。

但是,如果可能的话,我希望转移到标准的IoC容器,因为可能它们具有更多功能,不需要特定类型,并且当然更加标准化。但是在阅读它们时,我没有看到任何明显的迹象表明它们支持我的第二种方法。换句话说,它们都支持标准的两种生活方式(单身和短暂的),但我想要一些不同的东西:每个对象身份的单身。标准IoC容器是否支持此功能?怎么样?哪些?

对不起,如果这是一个基本问题。

2 个答案:

答案 0 :(得分:1)

MEF使用“合同名称”通过Export支持此操作。这允许您使用指定的合同名称导出和导入:

[Import("bob", typeof(UserViewModel)]
public UserViewModel bobViewModel { get; set; }

Ken Smith编辑
请参阅下面的讨论,了解我们最终的结论,即IoC容器不支持开箱即用的这种行为,并且可能并非真正用于解决此问题。

答案 1 :(得分:0)

Spring.NET当然支持非单例命名对象。 Singleton是默认的DI行为,但您也可以指定也创建单个实例。

请参阅文档here