从视图加载新项目时注入新的依赖项集

发布于 2024-12-02 20:20:44 字数 2530 浏览 0 评论 0原文

我目前正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

玩心态 2024-12-09 20:20:44

内存中只有一个 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 the IRepository 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 of EditorViewModel every time, but the _repository instance is still the same, and is being passed into the EditorViewModel instance.

If you need a new instance of IRepository every time you create an instance of EditorViewModel you could use an Abstract Factory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文