DI容器中的自定义生命周期管理(wcf代理:Unity vs Castle Windsor)

时间:2010-07-06 13:23:52

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

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

使用 Castle Windsor DI容器实现WCF代理生活范围。

AbstractLifestyleManager命名空间实现抽象类Castle.MicroKernel.Lifestyle会覆盖3种方法:ResolveDisposeRelease。在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:无法访问容器的上下文,所以如何解析对象?)。

此致

1 个答案:

答案 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实用程序类已经创建用于缓存服务实例(它包含哈希表和一些实用方法,如GetRemoveAndDispose),但是它太简单了,不能粘贴它这里。