Unity(代替温莎城堡)有可能吗? [英] Is this possible with Unity (Instead of Castle Windsor)?

查看:106
本文介绍了Unity(代替温莎城堡)有可能吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

博客文章显示了一种方法用Castle Windsor和NSubstitute实现自动模拟.

This blog post shows a way to implement auto mocking with Castle Windsor and NSubstitute.

我不知道或使用温莎城堡,但我使用Unity和NSubstitute.

I don't know or use Castle Windsor, but I do use Unity and NSubstitute.

有没有办法使用Unity来显示他的内容?

Is there a way to do what he shows using Unity?

以下是该帖子的相关内容:

首先,在Windsor中注册一个ILazyComponentLoader:

First of all, register an ILazyComponentLoader into Windsor:

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

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

Then, the implementation of LazyComponentAutoMocker is simply this:

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

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

And you’re done! Here’s a simple unit test example using only the code from above:

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

推荐答案

使用Unity,您可以编写一个自定义容器扩展来进行自动模拟.

With Unity you can write a custom container extension which does the automocking.

基于此文章,您需要以下内容:

Based on this article, you need something like:

我的实现示例中存在一个错误:请参阅此SO问题: 固定代码如下:

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;
        }
    }
}

您可以在创建容器时注册它:

And you can register it when creating your cotainer:

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

这篇关于Unity(代替温莎城堡)有可能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆