Castle Windsor生活方式取决于构造函数参数

时间:2013-07-11 11:40:32

标签: c# castle-windsor

我正在使用Castle Windsor作为IoC容器,我想根据另一个来解析一个对象:

public MyService : IService
{
  public MyService(MyObject obj)
  {
  }
}

在哪里解决:

var service1 = container.Resolve<IService>( new { obj = obj1 });
var service2 = container.Resolve<IService>( new { obj = obj1 });

var service3 = container.Resolve<IService>( new { obj = obj2 });

我希望service1与service2(相同的引用)相同,而service3不同。 所以我需要一种与Singleton或Transient不同的生活方式。只要obj参数相同(通过引用),就应该返回相同的对象。

你知道如何实现这个目标吗?

2 个答案:

答案 0 :(得分:3)

我不知道内置解决方案,但您始终可以创建自己的ILifestyleManager 作为参考,您可以查看implementation of SingletonLifestyleManager

我从未真正研究过如何为Castle制作自定义生活方式(据我记得,我们为Unity做过一次),但通常的想法是决定何时要解决一个新实例(CreateInstance在Castle中代码)以及何时使用存储的值。

ConcurrentDictionary可以帮助您处理存储(虽然不知道Castle的burden做了什么,但您可能希望对此进行研究)。如果动态创建objs,请注意泄漏 - 您可能对ConditionalWeakTable感兴趣。

注意:我同意@Steven,在您的情况下obj通常应该是参数Create方法,但为了完整性,我还会直接回答。< / em>的

答案 1 :(得分:2)

我终于创建了一个像以下的IScopeAccessor:

public class PerConstructorScopeAccessor : IScopeAccessor
{
    private static IDictionary<int, ILifetimeScope> Cache = new ConcurrentDictionary<int, ILifetimeScope>();

    public ILifetimeScope GetScope(Castle.MicroKernel.Context.CreationContext context)
    {
        int key = GetContextKey(context);
        if (!Cache.ContainsKey(key))
            Cache.Add(key, new DefaultLifetimeScope());

        return Cache[key];
    }

    private int GetContextKey(Castle.MicroKernel.Context.CreationContext context)
    {
        int hash = 0;

        foreach (var value in context.AdditionalArguments.Values)
        {
            hash = HashCode.CombineHashCode(hash, value.GetHashCode());
        }

        return hash;
    }

    #region IDisposable

    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            disposed = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    #endregion
}

而不是使用LifestyleScoped<PerConstructorScopeAccessor>()

注册我的依赖项