我找到了不错的帖子:Singleton WCF Proxy。
使用 Castle Windsor DI容器实现WCF代理生活范围。
从AbstractLifestyleManager
命名空间实现抽象类Castle.MicroKernel.Lifestyle
会覆盖3种方法:Resolve
,Dispose
和Release
。在Release
方法中,我们可以访问上下文,我们可以从中解析服务实例。
我已经从下面复制了该帖子的代码(稍作修改):
public class SingletonWCFProxyLifestyleManager : AbstractLifestyleManager
{
private object instance;
public override object Resolve(Castle.MicroKernel.CreationContext context)
{
lock (base.ComponentActivator)
{
if (this.instance == null)
{
this.instance = base.Resolve(context);
}
else
{
ICommunicationObject communicationObject = this.instance as ICommunicationObject;
if (communicationObject != null &&
communicationObject.State == CommunicationState.Faulted)
{
try
{
communicationObject.Abort();
}
catch { }
this.instance = base.Resolve(context);
}
}
}
return this.instance;
}
public override void Dispose()
{
if (this.instance != null)
{
base.Release(this.instance);
}
}
public override void Release(object instance)
{
}
}
我想使用 Unity 容器提供相同的功能。看起来LifetimeManager
命名空间(以及可选的Microsoft.Practices.Unity
接口)的IRequiresRecovery
类专用于此。
班级提供的所有方法如下所示:
public class SingletonWCFProxyLifestyleManager : LifetimeManager, IRequiresRecovery
{
public override object GetValue()
{
throw new NotImplementedException();
}
public override void RemoveValue()
{
throw new NotImplementedException();
}
public override void SetValue(object newValue)
{
throw new NotImplementedException();
}
#region IRequiresRecovery Members
public void Recover()
{
throw new NotImplementedException();
}
#endregion
}
以下是问题:
如何在第二个示例(使用Unity)中提供相同的功能,就像在第一个示例中所做的那样(使用Castle Windsor)?
(PS:无法访问容器的上下文,所以如何解析对象?)。
此致
答案 0 :(得分:0)
我会尝试回答我的问题(我希望这是正确的......)。
我发现了这篇文章Writing Custom Lifetime Managers。我一直在努力实现我之前详细描述的解决方案,基于该帖子和前一篇文章:Singleton WCF Proxy。
以下是我创建的内容。当然,我必须测试该代码。第一眼看,它还可以,但我稍后会看到。
public class SingletonWCFProxyLifestyleManager : LifetimeManager, IRequiresRecovery, IDisposable
{
private static readonly object _locker = new object();
private Guid _key;
public SingletonWCFProxyLifestyleManager()
{
_key = Guid.NewGuid();
}
public override object GetValue()
{
Monitor.Enter(_locker);
object result = Storage.Instance.Get(_key);
if (result != null)
{
ICommunicationObject communicationObject = result
as ICommunicationObject;
//If the proxy is in faulted state, it's aborted and a new proxy is created
if (communicationObject != null &&
communicationObject.State == CommunicationState.Faulted)
{
try
{
communicationObject.Abort();
}
catch
{
}
Dispose();
return null; //Return before releasing monitor
}
Monitor.Exit(_locker);
}
return result;
}
public override void RemoveValue()
{
}
public override void SetValue(object newValue)
{
Storage.Instance.Set(_key, newValue);
TryToReleaseMonitor();
}
#region IRequiresRecovery Members
public void Recover()
{
TryToReleaseMonitor();
}
#endregion
private void TryToReleaseMonitor()
{
try
{
Monitor.Exit(_locker);
}
catch(SynchronizationLockException)
{
} // This is ok, just means we don't hold the lock
}
#region IDisposable Members
public void Dispose()
{
object result = Storage.Instance.Get(_key);
if (result != null)
{
try
{
Storage.Instance.RemoveAndDispose(_key);
}
catch
{
ICommunicationObject communicationObject = result as ICommunicationObject;
if (communicationObject != null)
{
communicationObject.Abort();
}
}
}
}
#endregion
}
Storage
实用程序类已经创建用于缓存服务实例(它包含哈希表和一些实用方法,如Get
或RemoveAndDispose
),但是它太简单了,不能粘贴它这里。