How are components removed with Castle 3.0?

蹲街弑〆低调 提交于 2019-12-10 13:05:20

问题


I have IWindsorContaner which exists for the whole application lifetime. For Unittests it is possible to register mocks/stubs, etc. under their Type. When the test is finished and the fixture is disposed the registered components in forthe test are remove with a self created method called "Unregister".

Now, I want to update to the latest Castle version which is 3.0. According to the 3.0 release notes something like

public void Unregister(string contextName, string registrationName)
{
   IWindsorContainer context = GetOrCreateContext(contextName);
   context.Kernel.RemoveComponent(registrationName);
}

is not possible anymore, because the IKernel.RemoveComponent method has been removed. The description to fix this is not really sufficient ("Try utilizing IHandlerSelectors.").

A simplified version of the fixture I use for unittests:

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

}

How can I remove components with Castle 3.0?


回答1:


Instead of trying to remove all components, just create a new IWindsorContainer and bind that to whatever GetOrCreateContext is checking against. Then you'll have a fresh new container that has nothing bound to it.




回答2:


I know Im late to the game but I came up against this same issue. My problem was that due to the size of the application, first run of Castle Windsor was very slow (1s+) and to create a new context for each and every test was becoming onerous (600 tests, 5min wait time on Castle Windsor only)

I based my solution on 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);
    }
}

and

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

Then wherever you set up windsor

        WindsorOverrider = new WindsorHandlerOverride();
        container.Kernel.AddHandlerSelector(WindsorOverrider);

And when you want to override castle windsor default behaviour in test

WindsorOverrider.OverrideBehaviour(typeof(IService), mock.Object);

And on test tear down call

WindsorOverrider.CleanUp();


来源:https://stackoverflow.com/questions/9501209/how-are-components-removed-with-castle-3-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!