【问题标题】:Custom lifetime management in DI containers (wcf proxy: Unity vs Castle Windsor)DI 容器中的自定义生命周期管理(wcf 代理:Unity vs Castle Windsor)
【发布时间】:2010-07-06 13:23:52
【问题描述】:

我找到了不错的帖子:Singleton WCF Proxy

它是关于使用Castle Windsor DI 容器实现WCF 代理生命周期的。

Castle.MicroKernel.Lifestyle 命名空间实现抽象类AbstractLifestyleManager 覆盖了3 个方法:ResolveDisposeRelease。在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 命名空间(以及可选的IRequiresRecovery 接口)中的LifetimeManager 类专用于此。

该类提供的所有方法如下所示:

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:无法访问容器的上下文,所以我如何解析对象?)。

问候

【问题讨论】:

    标签: c# wcf castle-windsor unity-container


    【解决方案1】:

    我会尝试回答我的问题(我希望是正确的..)。

    我发现这篇文章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 实用程序类已创建用于缓存服务实例(它包含哈希表和一些实用程序方法,如GetRemoveAndDispose),但在这里粘贴它太简单了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-06
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 1970-01-01
      • 2011-09-15
      相关资源
      最近更新 更多