这可能与Unity(而不是Castle Windsor)有关吗?

时间:2012-05-16 22:04:18

标签: inversion-of-control unity-container

blog post显示了使用Castle Windsor和NSubstitute实现自动模拟的方法。

我不知道或使用Castle Windsor,但我确实使用Unity和NSubstitute。

有没有办法做他用Unity演示的东西?


以下是帖子的相关内容:

首先,将ILazyComponentLoader注册到Windsor:

var c = new WindsorContainer();    
c.Register(Component.For<LazyComponentAutoMocker>());

然后,LazyComponentAutoMocker的实现就是这样:

public class LazyComponentAutoMocker : ILazyComponentLoader
{    
  public IRegistration Load(string key, Type service, IDictionary arguments)    
  {    
    return Component.For(service).Instance(Substitute.For(new[] { service }, null));    
  }    
}

你已经完成了!这是一个简单的单元测试示例,仅使用上面的代码:

[Test]
public void IDictionary_Add_Invoked()
{
  var dict = c.Resolve<IDictionary>();
  dict.Add(1, 1);
  dict.Received().Add(1, 1);
}

1 个答案:

答案 0 :(得分:3)

使用Unity,您可以编写自定义容器扩展来执行自动锁定。

根据此article,您需要以下内容:

编辑:我的实施示例中有一个错误:请参阅此问题NSubstitute and Unity

所以固定代码看起来像这样

public class AutoMockingContainerExtension : UnityContainerExtension
{
    protected override void Initialize()
    {
        var strategy = new AutoMockingBuilderStrategy(Container);

        Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
    }

    class AutoMockingBuilderStrategy : BuilderStrategy
    {
        private readonly IUnityContainer container;
        private readonly Dictionary<Type, object> substitutes 
           = new Dictionary<Type, object>();

        public AutoMockingBuilderStrategy(IUnityContainer container)
        {
            this.container = container;
        }

        public override void PreBuildUp(IBuilderContext context)
        {
            var key = context.OriginalBuildKey;

            if (key.Type.IsInterface && !container.IsRegistered(key.Type))
            {
                context.Existing = GetOrCreateSubstitute(key.Type);
                context.BuildComplete = true;
            }
        }

        private object GetOrCreateSubstitute(Type type)
        {
            if (substitutes.ContainsKey(type))
                return substitutes[type];

            var substitute = Substitute.For(new[] {type}, null);

            substitutes.Add(type, substitute);

            return substitute;
        }
    }
}

您可以在创建cotainer时注册它:

IUnityContainer container = new UnityContainer();
container.AddExtension(new AutoMockingContainerExtension());