Unity(代替温莎城堡)有可能吗? [英] Is this possible with Unity (Instead of Castle Windsor)?
问题描述
此博客文章显示了一种方法用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屋!