我正在使用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参数相同(通过引用),就应该返回相同的对象。
你知道如何实现这个目标吗?
答案 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>()