I have the following castle windsor fluent config code ...
container
.AddFacility<TypedFactoryFacility>()
.Register(
Component
.For<IXxxCache>()
.ImplementedBy<AppFabricXxxCache>()
.Named("AppFabricXxxCache")
.LifeStyle.FromContext(),
Component
.For<IXxxCache>()
.ImplementedBy<DatabaseXxxCache>()
.Named("DatabaseXxxCache")
.LifeStyle.FromContext(),
Component
.For<IXxxCacheFactory>()
.ImplementedBy<XxxCacheFactory>()
.DependsOn(new {cacheName})
);
The XxxCacheFactory is as follows ...
public class XxxCacheFactory : IXxxCacheFactory
{
private readonly IWindsorContainer _container;
private readonly string _cacheName;
public XxxCacheFactory(IWindsorContainer container, string cacheName)
{
_container = container;
_cacheName = cacheName;
}
public IXxxCache Create()
{
try
{
var cache = new DataCacheFactory().GetCache(_cacheName);
return _container.Resolve<IXxxCache>("AppFabricXxxCache", new {cache});
}
catch (DataCacheException)
{
return _container.Resolve<IXxxCache>("DatabaseXxxCache");
}
}
public void Release(IXxxCache component)
{
_container.Release(component);
}
}
I can get this working with the following code ...
[Test]
public void database_xxx_cache_returned_when_cache_does_not_exist()
{
ConfigurationManager.AppSettings["CacheName"] = "this_cache_does_not_exist";
var container = Castle.WindsorContainerBootStrap.BootStrapContainerAndRunInstallers<SingletonLifestyleManager>();
var factory = container.Resolve<IXxxCacheFactory>();
var cache = factory.Create();
}
Ideally I'd like to cut out the factory creation part and just have the container get the the correct implementation using the factory class I have, like so ...
[Test]
public void database_xxx_cache_returned_when_cache_does_not_exist()
{
ConfigurationManager.AppSettings["CacheName"] = "this_cache_does_not_exist";
var container = Castle.WindsorContainerBootStrap.BootStrapContainerAndRunInstallers<SingletonLifestyleManager>();
var cache = container.Resolve<IXxxCache>();
}
Is this possible? If so, what am I missing?
One of my colleagues pointed me at the factory method support of Windsor
Just adding this to my installer has got it working ...
container
.Register(
Component
.For<DataCacheFactory>()
.ImplementedBy<DataCacheFactory>()
.LifeStyle.Singleton
,
Component
.For<IXxxCacheFactory>()
.ImplementedBy<XxxCacheFactory>()
.DependsOn(new {cacheName})
.LifeStyle.Transient
,
Component
.For<IXxxCache>()
.UsingFactoryMethod(kernel => kernel.Resolve<IXxxCacheFactory>().Create())
,
Component
.For<IXxxCache>()
.ImplementedBy<AppFabricXxxCache>()
.Named("AppFabricXxxCache")
.LifeStyle.FromContext()
,
Component
.For<IXxxCache>()
.ImplementedBy<DatabaseXxxCache>()
.Named("DatabaseXxxCache")
.LifeStyle.FromContext()
);
I've also used the container to create the DataCacheFactory as that is apparently an expensive operation. So the usage is now ...
[Test]
public void database_xxx_cache_returned_when_cache_does_not_exist()
{
// ARRANGE
ConfigurationManager.AppSettings["CacheName"] = "this_cache_does_not_exist";
var container = Castle.WindsorContainerBootStrap.BootStrapContainerAndRunInstallers<SingletonLifestyleManager>();
// ACT
var cache = container.Resolve<IXxxCache>();
// ASSERT
Assert.That(cache, Is.InstanceOf<DatabaseXxxCache>());
// TIDYUP
container.Dispose();
}