Cómo reutilizar una dependencia transitoria en el mismo contexto con el contenedor DI de Castle Windsor
Si tengo la siguiente configuración, ¿cómo puedo configurar mi contenedor para usar la misma base de datos, cuando los objetos se crean en el mismo contexto?
public class Database { }
public interface IRepository { Database Database { get; } }
public interface IFooRepository : IRepository { }
public interface IBarRepository : IRepository { }
public class FooRepository : IFooRepository
{
public Database Database { get; private set; }
public FooRepository(Database database) { this.Database = database; }
}
public class BarRepository : IBarRepository
{
public Database Database { get; private set; }
public BarRepository(Database database) { this.Database = database; }
}
public class Consumer
{
public IFooRepository fooRepository { get; private set; }
public IBarRepository barRepository { get; private set; }
public Consumer(IFooRepository fooRepository, IBarRepository barRepository)
{
this.fooRepository = fooRepository;
this.barRepository = barRepository;
}
}
[TestClass]
public class ConfigurationTest
{
private IWindsorContainer container;
[TestMethod]
public void SameDatabaseIsUsed()
{
Consumer consumer = container.Resolve<Consumer>();
IFooRepository fooRepository = consumer.fooRepository;
IBarRepository barRepository = consumer.barRepository;
Assert.AreEqual(fooRepository.Database, barRepository.Database); //FAILS
}
[TestMethod]
public void DifferentDatabaseIsUsed()
{
Consumer consumer = container.Resolve<Consumer>();
IFooRepository fooRepository = consumer.fooRepository;
Consumer consumer2 = container.Resolve<Consumer>();
IBarRepository barRepository = consumer2.barRepository;
Assert.AreNotEqual(fooRepository.Database, barRepository.Database); //PASSES
}
[TestInitialize]
public void SetUp()
{
container = new WindsorContainer();
container.Register(
Component.For<Database>().ImplementedBy<Database>().LifeStyle.Transient,
AllTypes.FromThisAssembly()
.BasedOn<IRepository>().WithService.FromInterface()
.Configure(c => c.LifeStyle.Transient),
Component.For<Consumer>().ImplementedBy<Consumer>().LifeStyle.Transient
);
}
}
EDITAR: he intentado usar un estilo de vida personalizado, pero no puedo entender qué puedo usar para detectar que he cambiado de contexto
public class DatabaseLifestyleManager : AbstractLifestyleManager
{
private CreationContext context;
private Database database;
private Database Database
{
get
{
if (database == null) database = new Database();
return database;
}
set
{
database = null;
}
}
public override object Resolve(CreationContext context)
{
if (this.context!=null && this.context.??? == context.???)
return Database;
else
{
this.context = context;
Database = null;
return Database;
}
}
public override void Dispose()
{
database = null;
context = null;
}
}
......
Component.For<Database>().ImplementedBy<Database>().LifeStyle.Custom(typeof(DatabaseLifestyleManager)