2011-02-11 45 views
0

我刚刚开始尝试使用IoC容器。目前,我正在使用一个本土工厂来构建我的ViewModel,它有两种风格:单身和基于ID。换句话说,我的应用程序(按定义)一次只有一个房间,因此只有一个RoomViewModel,但许多用户可以在该房间中,所以我需要许多UserViewModel。但是我想确保对于UserId =“johnsmith”的用户,只创建一个UserViewModel,并且任何尝试检索该UserViewModel都将返回相同的实例。哪些IoC容器支持基于标识符返回特定对象?

我不知道这是否会有助于解释事情或迷惑他们,但是这是我目前使用要做到这一点的方法:

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"); 

的AB能够做到这一点解决了大量的数据绑定和同步问题,所以它不是一种容易让我放弃的模式。

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

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

回答

1

MEF通过Export使用“合同名称”支持此操作。这使您可以导出和合同名称进口规定:

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

通过肯史密斯
请参见下面的讨论我们的最终结论是,IoC容器不支持这种行为进行的编辑盒子,也许并不是真正旨在解决这个问题。

+0

这是否允许我在运行时指定*,我希望此UserViewModel适用于“Bob”(而不是在设计时)?迄今为止,我在MEF导出/导入属性的文档中没有读到任何内容,这让我相信,但我可能错了。 – 2011-02-11 17:50:49

+0

“Bob”和“Fred”的区别在于它们是不同的用户。换句话说,Web服务会在不同的点返回User对象的一些不同的实例,其中一些是UserId =“Bob”,一些是UserId =“John”等。我需要用UserViewModel包装这些User对象,但我只想为每个用户创建一个UserViewModel,尽管(在不同时间)Web服务可能会为同一个(真实世界)用户返回不同的User对象。那有意义吗? – 2011-02-11 18:55:29

0

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

请参阅文档here