是否有处置 TransientLifetimeManager

发布于 2024-11-04 22:25:03 字数 574 浏览 5 评论 0原文

我有一个 WPF 视图,它有一个相应的 ViewModel。所有实例都通过统一容器解析。因为我使用的是棱镜,所以我需要视图的两个独立实例将其添加到视图注册到的两个不同区域中。如果我尝试将一个实例添加到两个区域中,我会得到一个

InvalidOperationException:指定 元素已经是逻辑子元素 另一个元素的。断开连接 首先。

当视图添加到第二个区域时,因为它已经添加到第一个区域。

这个问题可以通过使用 TransientLifetimeManager 轻松解决,TransientLifetimeManager 总是返回一个新实例,因此两个区域都将填充一个独立的实例。

但我们决定在新用户登录时创建一个子容器。每个与会话相关的视图和视图模型都使用此子容器进行解析。当用户的会话结束时,子容器将被释放,以便每个会话相关的实例也被释放。但是使用 TransientLifetimeManager 统一容器无法处理这些实例。

我们需要的是一个生命周期管理器,它总是返回一个新实例,但也能够处理这些实例。身边已经有这样的终身经理了吗?或者还有其他方法可以实现我上面描述的目的吗?

I have a WPF view that has a corresponding ViewModel. All instances are resolved via an unity container. Because I'm using prism I need two independent instances of the view to add it into two different regions the view is registered to. If I'd try to add one instance into both regions I get an

InvalidOperationException: Specified
element is already the logical child
of another element. Disconnect it
first.

when the view is added into the second region because it is already added to the first region.

This problem can easily be solved by using a TransientLifetimeManager that always returns a new instance so both regions would be filled with an independent instance.

But we have decided to create a child container when a new user logs on. Every session related view and view model are resolved using this child container. When the user's session ends, the child container is disposed so that also every session related instances are disposed. But using a TransientLifetimeManager the unity container cannot dispose those instances.

What we need is a lifetime manager that always returns a new instance, but is also capable of disposing those instances. Is there already such an lifetime manager around? Or is there another way to achieve what I described above?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

七分※倦醒 2024-11-11 22:25:03

您想要的听起来像是 ContainerControlledLifetime 管理器的变体,它不维护单例实例,而是维护实例的集合。不幸的是,这不是内置的生命周期管理器之一。

您可以查看 ContainerControlledLifetimeManager 的代码,发现它很漂亮简单的。您的“SynchronizedGetValue”实现将始终返回 null(向容器发出需要实例化新实例的信号)。您可以只继承 ContainerControlledLifetimeManager 并重写该方法。

我已经写得差不多了我想我可以给你代码。 :)

public class ContainerTrackedTransientLifetimeManager :     
             ContainerControlledLifetimeManager
{
    protected override object SynchronizedGetValue()
    {
        return null;
    }
}

那应该可以。我还没有测试过它......从界面来看,它看起来像是为 1 对 1 LifetimeManager 到对象关系而设计的,但如果事实证明它不止于此,您可能必须重写 SetValue (添加到集合中)对象的集合)并处置(处置对象的集合)。这是该实现:

public class ContainerTrackedTransientLifetimeManager : 
             SynchronizedLifetimeManager, IDisposable
{
    private ConcurrentCollection<object> values = new ConcurrentCollection<object>();

    protected override object SynchronizedGetValue()
    {
        return null;
    }

    protected override void SynchronizedSetValue(object newValue)
    {
        values.Add(newValue);
    }

    public override void RemoveValue()
    {
        Dispose();
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected void Dispose(bool disposing)
    {

         var disposables = values.OfType<IDisposable>();
         foreach(var disposable in disposables)
         {
              disposable.Dispose();
         }
         values.Clear();
    }

我不确定哪个是正确的答案。让我知道你的情况如何。

What you want sounds like a variant of the ContainerControlledLifetime manager that does not maintain a singleton instance, but a collection of instances. Unfortunately this is not one of the built-in lifetime managers.

You can look at the code for the ContainerControlledLifetimeManager and see that it is pretty simple. Your "SynchronizedGetValue" implementation would always return null (signaling to the container that a new instance needs to be instantiated). You could just subclass ContainerControlledLifetimeManager and override that method.

I've pretty much written it. I suppose I could give you the code. :)

public class ContainerTrackedTransientLifetimeManager :     
             ContainerControlledLifetimeManager
{
    protected override object SynchronizedGetValue()
    {
        return null;
    }
}

That should work. I've not tested it... from the interface, it looks like it's designed for a 1 to 1 LifetimeManager to Object relationship, but if it turns out it is more than that, you might have to override SetValue (adds to a collection of objects) and dispose (disposes that collection of objects). Here's that implementation:

public class ContainerTrackedTransientLifetimeManager : 
             SynchronizedLifetimeManager, IDisposable
{
    private ConcurrentCollection<object> values = new ConcurrentCollection<object>();

    protected override object SynchronizedGetValue()
    {
        return null;
    }

    protected override void SynchronizedSetValue(object newValue)
    {
        values.Add(newValue);
    }

    public override void RemoveValue()
    {
        Dispose();
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected void Dispose(bool disposing)
    {

         var disposables = values.OfType<IDisposable>();
         foreach(var disposable in disposables)
         {
              disposable.Dispose();
         }
         values.Clear();
    }

I'm not sure which of these is the right answer. Let me know how it goes for you.

奶茶白久 2024-11-11 22:25:03

当您使用瞬态生命周期管理器(这是默认设置)时,Unity 不会保留对已创建实例的引用。

因此,当不再有对该实例的引用时,它将被GC。

When you use transient lifetime manager (which is the default), Unity does not keep a reference to the created instance.

Thus, when there are no more reference to the instance, it will be GCed.

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