我有一个具有相应ViewModel的WPF视图。所有实例都通过统一容器解析。因为我正在使用棱镜,所以我需要视图的两个独立实例将其添加到视图注册到的两个不同区域。如果我尝试在两个区域添加一个实例,我会得到一个
InvalidOperationException:已指定 元素已经是逻辑孩子了 另一个元素。断开它 第一
将视图添加到第二个区域时,因为它已添加到第一个区域。
使用始终返回新实例的TransientLifetimeManager可以轻松解决此问题,因此两个区域都将填充独立实例。
但我们决定在新用户登录时创建子容器。使用此子容器解析每个与会话相关的视图和视图模型。当用户的会话结束时,配置子容器,以便也处理每个会话相关的实例。但是使用TransientLifetimeManager,统一容器不能处理这些实例。
我们需要的是一个终生管理器,它总是返回一个新实例,但也能够处理这些实例。是否已经有这样的终身经理?或者有另一种方法来实现我上面描述的内容吗?
答案 0 :(得分:2)
你想要的东西听起来像是ContainerControlledLifetime管理器的一个变体,它不维护单例实例,而是一组实例。不幸的是,这不是内置的终身经理之一。
您可以查看code for the ContainerControlledLifetimeManager,看看它非常简单。您的“SynchronizedGetValue”实现将始终返回null(向容器发信号通知需要实例化新实例)。您可以将ContainerControlledLifetimeManager子类化并覆盖该方法。
我写得很多。我想我可以给你代码。 :)
public class ContainerTrackedTransientLifetimeManager :
ContainerControlledLifetimeManager
{
protected override object SynchronizedGetValue()
{
return null;
}
}
那应该有用。我没有对它进行测试......从界面来看,它看起来像是为1对1的LifetimeManager到对象关系设计的,但如果事实证明它不止于此,你可能必须覆盖SetValue(添加到集合中)对象)和dispose(处置该对象集合)。这是实施:
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();
}
我不确定这些是正确的答案。让我知道它是怎么回事。
答案 1 :(得分:1)
当您使用临时生命周期管理器(这是默认值)时,Unity不会保留对创建的实例的引用。
因此,当没有对实例的更多引用时,它将被GCed。