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

标签 c# wcf castle-windsor unity-container

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

它是关于使用CaSTLe Windsor DI 容器实现WCF 代理生命范围。

来自 CaSTLe.MicroKernel.Lifestyle 命名空间的抽象类 AbstractLifestyleManager 的实现覆盖了 3 个方法:ResolveDispose发布。在 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 实用类已创建用于缓存服务实例(它包含哈希表和一些实用方法,如 GetRemoveAndDispose) , 但粘贴在这里太简单了。

关于c# - DI 容器中的自定义生命周期管理(wcf 代理 : Unity vs CaSTLe Windsor),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3186532/

相关文章:

c# - 为什么 "dynamic"需要特定于语言的运行时组件?

wcf - 使用 'UriTemplate' 的端点不能与 'System.ServiceModel.Description.WebScriptEnablingBehavior' 一起使用

asp.net-mvc-2 - 如何使用 CaSTLe Windsor 在 MVC 中注入(inject) UrlHelper

c# - 如何使用类型变量的类型参数创建表达式<Func<>>

c# - 至少一个对象必须在 Max() 中实现 IComparable

c# - 使用 PDFSharp 创建多个页面

c# - 错误 CS0030 : Cannot convert type 'Simple.Amazon.ECS.ImageSet[]' to 'Simple.Amazon.ECS.ImageSet' in Amazon Web Service

WCF REST 缓存 - 客户端和服务器端

c# - 如何使用 CaSTLe Windsor 注册通用装饰器?

c# - Microsoft 安全更新 MS13-004 后在 MSTest 中执行单元测试时出现 System.InvalidProgramException