我找到了不错的帖子:Singleton WCF Proxy .
它是关于使用CaSTLe Windsor DI 容器实现WCF 代理生命范围。
来自 CaSTLe.MicroKernel.Lifestyle
命名空间的抽象类 AbstractLifestyleManager
的实现覆盖了 3 个方法:Resolve
、Dispose
和 发布
。在 Release
方法中,我们可以访问 context,我们可以从中解析服务实例。
我从下面的帖子中复制了代码(稍作改动):
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 容器提供相同的功能。看起来 Microsoft.Practices.Unity
命名空间中的 LifetimeManager
类(以及可选的 IRequiresRecovery
接口(interface))专用于此。
该类提供的所有方法如下所示:
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:无法访问容器的上下文,所以我该如何解析对象?)。
问候
最佳答案
我会尝试回答我的问题(我希望正确..)。
我找到了这篇文章 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
) , 但粘贴在这里太简单了。
关于c# - DI 容器中的自定义生命周期管理(wcf 代理 : Unity vs CaSTLe Windsor),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3186532/