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

发布于 2024-09-08 05:19:56 字数 2498 浏览 4 评论 0原文

我发现了很好的帖子:单例 WCF 代理

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

来自 Castle.MicroKernel.Lifestyle 命名空间的抽象类 AbstractLifestyleManager 的实现重写了 3 个方法:ResolveDispose 和 <代码>发布。在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 容器提供相同的功能。看起来 Microsoft.Practices.Unity 命名空间中的 LifetimeManager 类(以及可选的 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)( using Castle Windsor)?

(PS:无法访问容器的上下文,那么我如何解析该对象?)。

问候

I've found nice post: Singleton WCF Proxy.

It is about the implementation of WCF proxy life scope using Castle Windsor DI container.

Implementation of the abstract class AbstractLifestyleManager from Castle.MicroKernel.Lifestyle namespace overrides 3 methods: Resolve, Dispose and Release. In the Release method we have access to the context, from which we can resolve service instance.

I've copied the code from that post (with a small change) below:

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)
    {

    }
}

I would like to provide the same functionality using Unity container. It looks like the LifetimeManager class from Microsoft.Practices.Unity namespace (and optionally IRequiresRecovery interface) is dedicated for that.

All methods that class is providing are shown below:

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
}

And here is the question:

How to provide the same functionality in the second example (using Unity), as it was done in the first example (using Castle Windsor) ?

(PS: There is no access to the context of the container, so how I can resolve the object ?).

Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

多孤肩上扛 2024-09-15 05:19:56

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

我找到了这篇文章编写自定义生命周期管理器。我一直在尝试根据该帖子和上一篇文章来实现我之前详细描述的解决方案: 单例 WCF 代理

以下是我创建的。当然,我必须测试该代码。乍一看,还不错,但我稍后会看到。

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),但它太简单了,无法粘贴到这里。

I'll try to answer my question (I hope that correctly..).

I've found this post Writing Custom Lifetime Managers. I've been trying to implement solution I've described previously in details, based on that post and the previous one: Singleton WCF Proxy.

Below is what I have created. Of course I have to test that code. For the first look, it is rather ok, but I'll see later.

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 utility class has been created for caching instances of services (it contains hashtable ans a few utility methods, like Get or RemoveAndDispose), but it is too simple for pasting it here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文