Unity Container:默认情况下,使用ContainerControlledLifetimeManager作为“Resolve”方法组

时间:2009-09-04 07:25:50

标签: .net dependency-injection singleton unity-container

如何填写TODO以使此测试通过?

class MyClass { }

[Test]
public void Singleton_by_default_test()
{
    var parentContainer = GetUnityContainer();        
    var container = parentContainer.GetChildContainer();

    // TODO: Add magic here (but do NOT explicitly register MyClass in container!)

    Assert.AreSame(container.Resolve<MyClass>(), container.Resolve<MyClass>());
}

更新 有一种方法可以使用继承。

public class SingletonContainer : UnityContainer
{
    public override object Resolve(Type t, string name)
    {
        var obj = base.Resolve(t, name);
        RegisterInstance(t, name, obj, new ContainerControlledLifetimeManager());
        return obj;
    }
}

我正在使用 container.GetChildContainer()来获取容器实例,所以这个方法不适合我。

2 个答案:

答案 0 :(得分:4)

我知道你要去哪里。有趣的问题。

我认为你可以用Unity Behavior Extension做你正在做的事情。这是一篇关于Unity设计的精彩文章,描述了很多人不了解的Unity某些元素的工作: http://msdn.microsoft.com/en-us/library/dd140062.aspx

Unity Container在处理解析请求时基本上使用“策略链”。链中的一个策略是LifetimeStrategy

最简单的方法是创建一个新策略并将其插入LifetimeStrategy之前的链中,以便当您的策略有机会查看该类型时,它可以为该类型注册ContainerControlledLifetimeManager在当前的容器中。它将进入LifetimeStrategy,并且已经有一个为该类型注册的ContainerControlledLifetimeManager。

可能看起来像这样:

public class MakeEverythingSingletonStrategy : BuilderStrategy
{
     public override void PreBuildUp(IBuilderContext context)
     {
          Type objectType = BuildKey.GetType(context.BuildKey);
          context.PersistentPolicies.Set<ILifetimePolicy>(
                  new SingletonLifetimePolicy(), 
                  context.BuildKey);

     }
}

您应该能够使用Configure<T>方法将此配置应用于子容器,并传入添加此新扩展的配置类。

我在Stackoverflow上找到了一个很好的样本,实现了一个自定义的BuilderStrategy:

Custom object factory extension for Unity

答案 1 :(得分:0)

尝试将其用作单身人士。 您可以为MyClass使用以下配置:*

<type type="MyClass" mapTo="MyClass">
  <lifetime type="singleton" />
</type>