Как удалить компоненты с помощью Castle 3.0? - PullRequest
7 голосов
/ 29 февраля 2012

У меня есть IWindsorContaner, который существует на протяжении всего времени жизни приложения. Для юнит-тестов можно зарегистрировать макеты / заглушки и т. Д. Под их типом. Когда тест завершен, и прибор утилизирован, зарегистрированные компоненты для теста удаляются с помощью самостоятельно созданного метода под названием «Unregister».

Теперь я хочу обновить приложение до последней версии 3.0. Согласно заметкам о выпуске 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?

Ответы [ 2 ]

2 голосов
/ 08 марта 2012

Вместо того, чтобы пытаться удалить все компоненты, просто создайте новый IWindsorContainer и привяжите его к тому, с чем GetOrCreateContext проверяет. Тогда у вас будет новый новый контейнер, с которым ничего не связано.

0 голосов
/ 04 мая 2018

Я знаю, что опоздал на игру, но столкнулся с этой же проблемой.Моя проблема заключалась в том, что из-за размера приложения первый запуск Castle Windsor был очень медленным (1 с +), и создание нового контекста для каждого теста становилось обременительным (600 тестов, 5 минут ожидания только на Castle Windsor)

Я основал свое решение на Как удалить компонент в 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);

И когда вы хотите переопределить поведение замка Виндзора по умолчанию в тесте

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

И при тестовом разрыве вызова

WindsorOverrider.CleanUp();
...