【发布时间】:2020-02-06 11:52:10
【问题描述】:
如何在 WPF 应用程序中获取最内部的 autofac 范围或命名范围? 我需要这个,因为我使用 MarkupExtension 来解析 VM。所以在我的 MarkupExtension 中,我需要当前(最里面的)Lifetimescope。
谢谢
【问题讨论】:
标签: wpf mvvm autofac markup-extensions lifetime-scoping
如何在 WPF 应用程序中获取最内部的 autofac 范围或命名范围? 我需要这个,因为我使用 MarkupExtension 来解析 VM。所以在我的 MarkupExtension 中,我需要当前(最里面的)Lifetimescope。
谢谢
【问题讨论】:
标签: wpf mvvm autofac markup-extensions lifetime-scoping
我找到了一个方法...
Container 有一个事件ChildLifetimeScopeBeginning(object sender, ILifetimeScopeBeginningEventArgs args),我可以将它用于我的 MakupExtensions,如下所示:
Container.ChildLifetimeScopeBeginning += (sender, args) =>
{
Debug.Write($"Begin new LifetimeScope: {args.LifetimeScope.Tag??"Unnamed"}");
//Set the current Lifetime scope for the MarkupExtension
ContainerTypeResolverExtension.Container = args.LifetimeScope;
};
所以现在,当创建每个新范围时,我可以替换 MarkupExtension 内部容器。 如果有更好的方法,我全力以赴。
【讨论】:
WPF 应用程序没有原生的“请求生命周期”集成。如果您正在创建嵌套的生命周期范围,则由您来跟踪它们。是否需要跟踪您自己的生命周期范围 - 无论是创建还是处置 - 都取决于您。也许你设置了某种局部变量,也许你有其他机制。
但是,只是在容器上添加一个事件处理程序是行不通的。
每个生命周期范围都有自己的子生命周期范围开始的事件。
假设你有这个:
var builder = new ContainerBuilder();
var container = builder.Build();
var scope1 = container.BeginLifetimeScope();
var scope2 = scope1.BeginLifetimeScope();
var scope3 = scope1.BeginLifetimeScope();
将事件附加到容器不会找到嵌套在容器外部的范围。它会看到scope1,但不会看到scope2 或scope3。
您也没有解释您在使用“最嵌套的生命周期范围”做什么,因此不清楚其中哪些是“最嵌套的” - 似乎 scope2 和 scope3 是同样嵌套的,那么哪个是正确的呢?
最后,还有线程问题需要考虑。如果您在异步方法中生成生命周期范围或执行任何不同线程将创建不同范围的操作,那么简单地跟踪 [基本上] 最后创建的范围会给您带来麻烦,最终您将尝试从存在于不再存在的线程上的作用域。
在真正非常有限的情况下,您没有执行多线程/异步并且永远没有嵌套的生命周期范围,也许处理事件是可以的。 我不建议该问题的未来读者遵循此路径。
由于没有给出上下文,因此无法提供更好的方法。你有范围的参考吗?你能把它传递给方法而不是试图神奇地定位它吗?有很多方法可以解决这个问题,但这里还不足以提供一个好的答案。考虑对此进行更多搜索,如果仍然没有产生任何结果,请提出一个包含更多信息的新问题,也许是重现,以及对您尝试过的内容的更多解释。
【讨论】: