gpt4 book ai didi

c# - 统一容器 : Using PerResolveLifetimeManager and custom interception

转载 作者:太空狗 更新时间:2023-10-29 20:37:53 24 4
gpt4 key购买 nike

我正在尝试实现自己的拦截,同时仍然使用 Unity 容器。我想以尊重所使用的生命周期管理器的方式来做到这一点。即,如果它是 PerResolveLifetimeManager,那么我想包装实例一次,并且我希望在整个解析过程中使用该包装实例。

到目前为止,我实现了一个 BuilderStrategy,我使用自定义 UnityContainerExtension 类将其添加到我的容器中(我将 PostInitialization 传递给 AddNew 方法;我不确定最合适的值是什么,但这似乎有效)。在我的 BuilderStrategy 中的 PostBuildUp 覆盖中,我将 context.Existing 替换为我的包装值。

当我将它与 PerResolve 生命周期一起使用时,会发生一次包装,但只有第一次使用依赖项时才会获得包装实例,其余的会获得非包装实例。即,如果我的 ctor 接受 IFoo foo1 和 IFoo foo2,那么只有 foo1 是我包装的实例,而 foo2 是未包装的实例。

这是一个示例重现(为简单起见,我使用另一个类 Foo2 的实例,而不是包装):

public class MyInterception : UnityContainerExtension
{
protected override void Initialize()
{
Context.Strategies.AddNew<MyInterceptionStrategy>(UnityBuildStage.PostInitialization);
}
}

public class MyInterceptionStrategy : BuilderStrategy
{
public override void PostBuildUp(IBuilderContext context)
{
if (!context.OriginalBuildKey.Type.IsInterface)
{
return;
}

context.Existing = new Foo2();
}
}

public class Bar
{
public Bar(IFoo f1, IFoo f2, IFoo f3)
{
}
}

public interface IFoo
{
}

public class Foo1 : IFoo
{
}

public class Foo2 : IFoo
{
}

public void Main()
{
UnityContainer container = new UnityContainer();
container.AddNewExtension<MyInterception>();
container.RegisterType(typeof (IFoo), typeof (Foo1), new PerResolveLifetimeManager());

container.Resolve<Bar>();
}

如果你在 PostBuildUp 和 Bar 的构造函数中放置一个断点,并通过 Bar 的 resolve 调试 Main up,你可以看到 PostBuildUp 只被调用一次。但是,在 Bar 的构造函数中,f1 是 Foo2 的实例(“包装”实例),而 f2 和 f3 是 Foo1 的实例(未包装)。

我想知道我想要的东西是否可行,我是否采用了正确的方法?我的问题是否与我为其添加 BuilderStrategy 的生命周期和/或 UnityBuildStage 有关?

谢谢

最佳答案

您在构建策略中执行拦截策略的时间太晚了。不幸的是,目前我没有更详细的原因来解释 为什么 代码在 ObjectBuilder 程序集中以这种方式运行。

希望当我有更多时间分析 Unity ObjectBuilder 时我会回来,但要在此期间解决您的问题,只需更改您的 UnityBuildStagePostInitializationSetupTypeMapping

的枚举值
Context.Strategies.AddNew<MyInterceptionStrategy>(UnityBuildStage.Setup);

我的完整代码:

using System;
using Microsoft.Practices.ObjectBuilder2;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.ObjectBuilder;

namespace UnityInterceptors
{
class Program
{
public class MyInterception : UnityContainerExtension
{
protected override void Initialize()
{
Context.Strategies.AddNew<MyInterceptionStrategy>(UnityBuildStage.Setup);
}
}
public class MyInterceptionStrategy : BuilderStrategy
{
public override void PostBuildUp(IBuilderContext context)
{
if (!context.OriginalBuildKey.Type.IsInterface)
{
return;
}

context.Existing = new Foo2();
}
}

public class Bar
{
public Bar(IFoo f1, IFoo f2, IFoo f3)
{
Console.WriteLine(f1.GetType().Name);
Console.WriteLine(f2.GetType().Name);
Console.WriteLine(f3.GetType().Name);
}
}

public interface IFoo
{
}

public class Foo1 : IFoo
{
}

public class Foo2 : IFoo
{
}

public static void Main()
{
UnityContainer container = new UnityContainer();
container.AddNewExtension<MyInterception>();
container.RegisterType(typeof(IFoo), typeof(Foo1), new PerResolveLifetimeManager());

container.Resolve<Bar>();

Console.ReadLine();
}
}
}
  • 另请注意,我使用的是 Unity 2.0 库。可能是某种类型的错误已得到解决。

关于c# - 统一容器 : Using PerResolveLifetimeManager and custom interception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3062199/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com