温莎城堡的生活方式取决于建造商的参数
本文关键字:参数 生活方式 城堡 取决于 | 更新日期: 2023-09-27 18:22:01
我使用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不同。所以我需要一种不同于辛格尔顿或瞬态的生活方式。只要obj参数相同(通过引用),就应该返回相同的对象。
你知道如何做到这一点吗?
我不知道有内置的解决方案,但您总是可以创建自己的ILifestyleManager
作为参考,您可以查看SingletonLifestyleManager的实现。
我从未真正研究过如何为Castle定制生活方式(据我记忆所及,我们为Unity做过一次),但通常的想法是决定何时解析新实例(Castle代码中的CreateInstance
)以及何时使用存储值。
ConcurrentDictionary
可以在您的情况下帮助存储(尽管不知道Castle的burden
做什么,但您可能想研究一下)。如果您的objs
是动态创建的,请注意泄漏——您可能对ConditionalWeakTable
感兴趣。
注意:我同意@Steven的观点,在你的情况下,obj
通常应该是一个参数Create
方法,但为了完整性,我也会保留一个直接的答案
我终于创建了一个类似于的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>()
注册我的依赖项