Individual lifecycle management in DI containers (wcf proxy: Unity vs Castle Windsor)

I found a good post: Singleton WCF Proxy .

It's about implementing the WCF proxy life cycle using the Castle Windsor container .

Performing an abstract class AbstractLifestyleManagerfrom Castle.MicroKernel.Lifestylethe namespace override 3 methods: Resolve, Disposeand Release. In the method, Releasewe have access to the context from which we can resolve the service instance.

I copied the code from this post (with a slight 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)
    {

    }
}

, 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: , ?).

+3
1

(, ..).

. , : 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 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), .

0

Source: https://habr.com/ru/post/1753310/


All Articles