如果我具有以下设置,那么在同一上下文中创建对象时,如何配置我的容器以使用同一数据库

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

    }
}


编辑:
我试图使用自定义的生活方式,但是我无法弄清楚我可以用来检测是否切换了上下文

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)

最佳答案

请求瞬态组件时,您总是会得到一个新实例,如果不是您想要的实例,请不要使用瞬态生活方式:-)

您为什么要注册一个瞬态组件,而尝试根据某种“上下文”来解析同一对象?生活方式很可能是这种情况的错误,而您会很难将其强迫为并非如此。

您想要的是类似于this article中提到的上下文生活方式。
以下两个要点对此有一个实现:


http://gist.github.com/400979
http://gist.github.com/400980


这将允许您执行以下操作:

Register(Component.For<Database>().LifeStyle.Scoped())

[TestMethod]
public void SameDatabaseIsUsed()
{
    using (container.BeginScope())
    {
        Consumer consumer = container.Resolve<Consumer>();
        IFooRepository fooRepository = consumer.fooRepository;
        IBarRepository barRepository = consumer.barRepository;
        Assert.AreEqual(fooRepository.Database, barRepository.Database); // YAY!
    }
}


希望这可以帮助!

关于dependency-injection - 如何在相同的上下文中使用CaSTLe Windsor DI容器重用 transient 依赖项,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3986747/

10-16 08:57