我有IWindsorContaner,它存在于整个应用程序生命周期中。对于Unittests,可以在其类型下注册模拟/存根等。当测试完成并且夹具被丢弃时,测试中的注册组件将被自动创建的方法“Unregister”删除。
现在,我想更新到3.0的最新Castle版本。根据3.0发布说明,如
public void Unregister(string contextName, string registrationName)
{
IWindsorContainer context = GetOrCreateContext(contextName);
context.Kernel.RemoveComponent(registrationName);
}
不再可能,因为已删除了IKernel.RemoveComponent方法。解决这个问题的描述还不够(“尝试使用IHandlerSelectors。”)。
我用于单元测试的夹具的简化版本:
public sealed class DependencyInjectionFixture : IDisposable
{
private Stack<Type> registeredTypes = new Stack<Type>();
// Registering of mocks/stubs, etc
public void RegisterSingleton<T>(T singleton, string objectName)
{
registeredTypes.Push(typeof(T));
IWindsorContainer context = GetOrCreateContext(contextName);
context.Register(Component.For(typeof(T))
.Named(objectName)
.Instance(singleton)
.LifeStyle.Singleton);
}
// Called when tests ends
public void Dispose()
{
IWindsorContainer context = GetOrCreateContext(contextName);
while (registeredTypes.Count > 0)
context.Kernel.RemoveComponent(CSApplicationContext.GetRegistrationNameFor(registeredTypes.Pop()));
}
}
如何使用Castle 3.0删除组件?
答案 0 :(得分:2)
不要尝试删除所有组件,只需创建一个新的IWindsorContainer
并将其绑定到正在检查的GetOrCreateContext
。然后你将拥有一个没有任何约束力的新容器。
答案 1 :(得分:0)
我知道我迟到了,但我遇到了同样的问题。 我的问题是,由于应用程序的大小,Castle Windsor的第一次运行速度非常慢(1s +)并为每个测试创建一个新的上下文变得繁重(600次测试,仅在Castle Windsor上等待5分钟)< / p>
我的解决方案基于How to remove component in Castle Windsor 3.0?
public class WindsorHandlerOverride : IHandlerSelector
{
private Dictionary<Type, object> definedTypeBehaviours;
public bool HasOpinionAbout(string key, Type service)
{
return definedTypeBehaviours.IsNotNullAndAny(t => t.Key == service);
}
public IHandler SelectHandler(string key, Type service, IHandler[] handlers)
{
var theValue = definedTypeBehaviours[service];
return new WindsorSimpleHandler {TheValue = theValue};
}
public void CleanUp()
{
definedTypeBehaviours = null;
}
public void OverrideBehaviour(Type type, object value)
{
if (definedTypeBehaviours == null)
{
definedTypeBehaviours = new Dictionary<Type, object>();
}
definedTypeBehaviours.Add(type, value);
}
}
和
public class WindsorSimpleHandler : IHandler
{
public object TheValue { get; set; }
public ComponentModel ComponentModel { get; set; }
public HandlerState CurrentState { get; set; }
public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model,
DependencyModel dependency)
{
return true;
}
public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model,
DependencyModel dependency)
{
return TheValue;
}
public object Resolve(CreationContext context)
{
return TheValue;
}...
然后无论你在哪里设置windsor
WindsorOverrider = new WindsorHandlerOverride();
container.Kernel.AddHandlerSelector(WindsorOverrider);
当你想在test
中覆盖castle windsor默认行为时WindsorOverrider.OverrideBehaviour(typeof(IService), mock.Object);
关于测试拆机电话
WindsorOverrider.CleanUp();