PageRenderTime 25ms CodeModel.GetById 17ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/src/LinFu.IoC/Configuration/InitializerOfT.cs

http://github.com/philiplaureano/LinFu
C# | 114 lines | 65 code | 21 blank | 28 comment | 14 complexity | 9cbdc14f75655f20ba354f99d072a16c MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using LinFu.IoC.Interfaces;
  4using LinFu.Reflection;
  5
  6namespace LinFu.IoC.Configuration
  7{
  8    /// <summary>
  9    ///     A class that initializes service instances that use
 10    ///     the <see cref="IInitialize{T}" /> interface.
 11    /// </summary>
 12    public class Initializer<T> : IPostProcessor
 13    {
 14        private static readonly HashSet<HashableWeakReference> _instances =
 15            new HashSet<HashableWeakReference>(new HashableWeakReferenceComparer());
 16
 17        private static int _initializeCallCount;
 18        private readonly Func<IServiceRequestResult, T> _getSource;
 19
 20        /// <summary>
 21        ///     Initializes the class with the given <paramref name="getSource" /> delegate.
 22        /// </summary>
 23        /// <param name="getSource">
 24        ///     The functor that will obtain the object instance that will be used to initialize a given
 25        ///     service.
 26        /// </param>
 27        public Initializer(Func<IServiceRequestResult, T> getSource)
 28        {
 29            _getSource = getSource;
 30        }
 31
 32
 33        /// <summary>
 34        ///     Initializes every service that implements
 35        ///     the <see cref="IInitialize{T}" /> interface.
 36        /// </summary>
 37        /// <param name="result">
 38        ///     The <see cref="IServiceRequestResult" /> instance that contains the service instance to be
 39        ///     initialized.
 40        /// </param>
 41        public void PostProcess(IServiceRequestResult result)
 42        {
 43            var originalResult = result.OriginalResult as IInitialize<T>;
 44            var actualResult = result.ActualResult as IInitialize<T>;
 45
 46            var source = _getSource(result);
 47
 48            // Initialize the original result, if possible
 49            Initialize(originalResult, source);
 50
 51            // Initialize the actual result
 52            Initialize(actualResult, source);
 53        }
 54
 55
 56        /// <summary>
 57        ///     Initializes the <paramref name="target" /> with the given <paramref name="source" /> instance.
 58        /// </summary>
 59        /// <param name="target">The target to initialize.</param>
 60        /// <param name="source">The instance that will be introduced to the <see cref="IInitialize{T}" /> instance.</param>
 61        private static void Initialize(IInitialize<T> target, T source)
 62        {
 63            if (target == null)
 64                return;
 65
 66            if ((_initializeCallCount = ++_initializeCallCount % 100) == 0)
 67                _instances.RemoveWhere(w => w != null && !w.IsAlive);
 68
 69            // Make sure that the target is initialized only once
 70            var weakReference = new HashableWeakReference(target);
 71            if (_instances.Contains(weakReference))
 72                return;
 73
 74            // Initialize the target
 75            target.Initialize(source);
 76            _instances.Add(weakReference);
 77        }
 78
 79
 80        private class HashableWeakReference : WeakReference
 81        {
 82            private readonly int _hashCode;
 83
 84            public HashableWeakReference(object target)
 85                : base(target, false)
 86            {
 87                _hashCode = target.GetHashCode();
 88            }
 89
 90            public override int GetHashCode()
 91            {
 92                return _hashCode;
 93            }
 94        }
 95
 96
 97        private class HashableWeakReferenceComparer : IEqualityComparer<HashableWeakReference>
 98        {
 99            public bool Equals(HashableWeakReference x, HashableWeakReference y)
100            {
101                if (x == null || y == null)
102                    return false;
103
104                return x.Target == y.Target;
105            }
106
107            int IEqualityComparer<HashableWeakReference>.GetHashCode(HashableWeakReference obj)
108            {
109                if (obj == null) throw new ArgumentNullException("obj");
110                return obj.GetHashCode();
111            }
112        }
113    }
114}