从视图加载新项目时注入新的依赖项集
我目前正在使用 Castle Windsor v2.5.1 并遇到了一些问题。我有一个列表,用户可以在其中选择他们选择的项目并开始处理所选项目。当选择一个项目时,我将构建的项目注入编辑器视图模型中并将其显示给最终用户。我已将所有依赖项设置为具有短暂的生活方式,这导致我需要处理注入的单例依赖项,从而使我留下来自先前加载的项目的陈旧数据,而不是新对象。
我的视图模型构造函数如下所示:
public TabViewModel(
IRepository repository
IEditorViewModelFactory editorViewModelFactory)
{
在该应用程序的生命周期内仅创建该类的一个实例,这很好。但由于用户可以(并且确实)在应用程序的整个生命周期中选择许多不同的项目,因此我最终使用了相同的依赖项。每次在 TabViewModel
视图中选择一个新项目时,我都会调用 editorViewModelFactory.Create(所选项目的 id)
。由于只创建了一个 IEditorViewModelFactory
实例,因此 Windsor 不注入新的依赖项是有道理的。
每当加载新项目时,如何强制 Windsor 注入一组新的依赖项?
编辑
该应用程序的工作原理如下。当应用程序加载时,它会打开与 TabViewModel
类关联的视图并注入它的两个依赖项。仅创建了一个 TabViewModel
实例。在这个 TabViewModel
对象中,我挂钩到 TreeViewItem
中的 IsSelected
属性(所有项目都存储在树视图中。选择一个项目后,将执行以下操作)来自 TabViewModel
的事件被触发。我获取了选定的项目,并从注入的 IEditorViewModelFactory
中加载适当的编辑器,
private void OnItemSelected(object sender, PropertyChangedEventArgs e)
{
const string isSelected = "IsSelected";
var selectedItem = sender as ItemViewModelTiny;
if (e.PropertyName == isSelected && selectedItem.IsSelected)
{
_editorViewModelFactory.Create(selectedItem.Id);
}
}
因为只有一个 TabViewModel
。然后创建它只创建一个 IEditorViewModelFactory
是有道理的,因此,即使我在选择某个项目时不断调用 Create()
,它也使用与第一个项目创建时创建的相同依赖项。 希望
我的工厂如下所示:
public class EditorViewModelFactory : IEditorViewModelFactory
{
private readonly IRepository _repository;
public EditorViewModelFactory(IRepository repository)
{
_repository = repository;
}
public LocateEditorViewModel Create(int itemId)
{
var fullItem = _repository.GetFullItem(itemId);
return new EditorViewModel(_repository, fullItem.MapTo<ItemViewModel>());
}
}
这能澄清我的问题。
编辑 2
每次选择一个项目时,我都会使用我的评论服务来确定用户的资格,同时我会检索所选项目的所有当前评论。已对其进行审查由我的评论处理器处理,并根据确定用户资格收集的评论进行处理。这意味着,通过始终拥有相同的评论服务实例,所有先前从其他项目检索到的评论都会在系统中徘徊。我只需在查找用户资格时清除评论列表即可解决此问题。这是有效的,因为当加载编辑器时,首先发生的事情是确定用户是否符合资格。
这是我提到的两个界面:
public interface IReviewingService
{
ReviewEligibilityResult GetReviewEligibility(ItemViewModel itemViewModel);
void Save(UserReview userReview);
}
public interface IReviewProcessor
{
void Process(UserReview userReview, IList<ReviewDto> reviews);
}
希望这是有道理的。
I'm currently using Castle Windsor v2.5.1 and running into a few issues. I have a list where users select an item of their choice and begin working on the item selected. When an item is selected I inject the built item in my editor view model and display it to the end user. I've set all of my dependencies to have a transient lifestyle, which is causing me to deal with getting singleton dependencies injected, leaving me with stale data from a previously loaded item instead of a new object.
Here is what my view model constructor looks like:
public TabViewModel(
IRepository repository
IEditorViewModelFactory editorViewModelFactory)
{
Only one instance of this class is ever created within the lifetime of this application which is fine. But since users can (and do) select many different items throughout the lifetime of the application I end up using the same dependencies. Everytime a new item is selected inside the TabViewModel
view I call editorViewModelFactory.Create(the id of the item selected)
. Since only one instance of IEditorViewModelFactory
is created it makes sense that Windsor isn't injection fresh dependencies.
How do I force Windsor to inject a fresh set of dependencies whenever a new item is loaded?
Edit
The application works as follows. When the application loads it opens up it opens the view associated to the TabViewModel
class and injects both of it's dependencies. Only one instance of TabViewModel
is ever created. Inside this TabViewModel
object I hook into the IsSelected
property from TreeViewItem
(all items are stored in a tree view. Once an item is selected the following event from TabViewModel
is fired. I get the item that was selected and load the appropriate editor from my injected IEditorViewModelFactory
.
private void OnItemSelected(object sender, PropertyChangedEventArgs e)
{
const string isSelected = "IsSelected";
var selectedItem = sender as ItemViewModelTiny;
if (e.PropertyName == isSelected && selectedItem.IsSelected)
{
_editorViewModelFactory.Create(selectedItem.Id);
}
}
Since only one TabViewModel
is ever created then it makes sense that only one IEditorViewModelFactory
is created. Thus, even though I keep calling Create()
when an item is selected it's using the same dependencies created from when the first item was loaded.
My factory looks as follows:
public class EditorViewModelFactory : IEditorViewModelFactory
{
private readonly IRepository _repository;
public EditorViewModelFactory(IRepository repository)
{
_repository = repository;
}
public LocateEditorViewModel Create(int itemId)
{
var fullItem = _repository.GetFullItem(itemId);
return new EditorViewModel(_repository, fullItem.MapTo<ItemViewModel>());
}
}
Hope this clarifies my question.
Edit 2
Every time an item is selected I use my reviewing service to determine the users eligibility. While determining the eligibility I retrieve all current reviews for the selected item. When an item is reviewed it gets processed by my review processor with the reviews gathered from determining the users eligibility. This means that by always having the same instance of the reviewing service all previously retrieved reviews from other items are lingering in the system. I was able to fix this problem by simply clearing my list of reviews when finding the users eligibility. This works because when the editor is loaded the first thing that happens is determine if the user is eligible.
Here are both of the interfaces I refer to:
public interface IReviewingService
{
ReviewEligibilityResult GetReviewEligibility(ItemViewModel itemViewModel);
void Save(UserReview userReview);
}
public interface IReviewProcessor
{
void Process(UserReview userReview, IList<ReviewDto> reviews);
}
Hope that makes sense.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
内存中只有一个
EditorViewModelFactory
实例,因为它被配置为单例。因此,由于它通过_repository
字段保存IRepository
实例,因此内存中也只有一个这些实例,没有无论其生命周期如何配置。但是,
Create
方法每次都会返回一个新的EditorViewModel
实例,但_repository
实例仍然相同,并且被传递到EditorViewModel
实例。如果每次创建
EditorViewModel
实例时都需要一个新的IRepository
实例,您可以使用抽象工厂。There's only one instance of
EditorViewModelFactory
in memory because it's configured as a Singleton. Thus, because it holds on to theIRepository
instance by the_repository
field, there's also only one of those instances in memory, no matter how its lifetime is configured.However, the
Create
method returns a new instance ofEditorViewModel
every time, but the_repository
instance is still the same, and is being passed into theEditorViewModel
instance.If you need a new instance of
IRepository
every time you create an instance ofEditorViewModel
you could use an Abstract Factory.