Skip to content

Instantly share code, notes, and snippets.

@blazey
Created June 18, 2015 10:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blazey/646b2e90e9454d827fd4 to your computer and use it in GitHub Desktop.
Save blazey/646b2e90e9454d827fd4 to your computer and use it in GitHub Desktop.
Windsor facility to swap registered components with configured test friendly substitutions.
internal class RegisterComponent<TService> where TService : class
{
private readonly Func<TService> _factory;
private readonly Type _componentType;
public static void Register(IWindsorContainer container, Func<TService> factory, Type componentType)
{
if (null == componentType)
{
new RegisterComponent<TService>(factory).Register(container);
}
else
{
new RegisterComponent<TService>(componentType).Register(container);
}
}
private RegisterComponent(Func<TService> factory)
{
_factory = factory;
}
private RegisterComponent(Type componentType)
{
if (componentType != typeof (TService))
{
throw new ArgumentOutOfRangeException();
}
_componentType = componentType;
}
internal void Register(IWindsorContainer container)
{
var service = typeof (TService);
var key = TestSubstituteFacility.TestKey(service);
var componentRegistration = Component.For<TService>().Named(key);
if (null == _componentType)
{
componentRegistration.UsingFactoryMethod(_factory);
}
else
{
componentRegistration.ImplementedBy(_componentType);
}
container.Register(componentRegistration);
}
}
internal class TestSubstituteFacility : AbstractFacility
{
private IWindsorContainer _container;
public TestSubstituteFacility WithContainer(IWindsorContainer container)
{
_container = container;
return this;
}
public TestSubstituteFacility Substitute<TService>(Action<TestSubstituteInstanceParams<TService>> config)
where TService : class
{
TestSubstituteInstanceParams<TService>.Config(_container, config);
return this;
}
internal static string TestKey(Type service)
{
return string.Format("{0}::{1}", typeof (TestSubstituteFacility).Name, service.FullName);
}
protected override void Init()
{
Kernel.AddHandlerSelector(new TestSubstituteHandlerSelector(_container));
}
}
internal class TestSubstituteHandlerSelector : IHandlerSelector
{
private readonly IWindsorContainer _container;
public TestSubstituteHandlerSelector(IWindsorContainer container)
{
_container = container;
}
public bool HasOpinionAbout(string key, Type service)
{
var testKey = TestSubstituteFacility.TestKey(service);
return _container.Kernel.HasComponent(testKey);
}
public IHandler SelectHandler(string key, Type service, IHandler[] handlers)
{
var testKey = TestSubstituteFacility.TestKey(service);
return _container.Kernel.GetHandler(testKey);
}
}
internal class TestSubstituteInstanceParams<TService> where TService : class
{
internal static TestSubstituteInstanceParams<TService> Config(IWindsorContainer container,
Action<TestSubstituteInstanceParams<TService>> config)
{
var args = new TestSubstituteInstanceParams<TService>();
config(args);
args.Register(container);
return args;
}
private Func<TService> _factory;
private Type _componentType;
public void Instance(Func<TService> factory)
{
_factory = factory;
}
public void Instance(TService instance)
{
_factory = () => instance;
}
public void Stub()
{
_factory = Mock.Of<TService>;
}
public void Component<TComponent>() where TComponent : TService
{
_componentType = typeof (TComponent);
}
internal void Register(IWindsorContainer container)
{
RegisterComponent<TService>.Register(container, _factory, _componentType);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment