/// <summary> /// Get an associate given an indexing object /// </summary> /// <param name='index'> /// The object to find the associate for /// </param> /// <typeparam name='T2'> /// The type of associate to find /// </typeparam> public T2 Get <T2>(object index) where T2 : T, new() { //Get the hash code of the indexing object var hash = index.GetHashCode(); List <WeakEntry> entries; //See if we have a reference already if (!references.TryGetValue(hash, out entries)) { //If not the create the reference list references[hash] = entries = new List <WeakEntry>(); } //See if we have an object of the correct type and that the //reference is still alive var item = entries.FirstOrDefault(e => e.weakReference.IsAlive && e.weakReference.Target == index && e.associate is T2); if (item == null) { //If not create one entries.Add(item = new WeakEntry { weakReference = new WeakReference(index), associate = new T2() }); } //Return the associate return((T2)item.associate); }
public override TItem Add(TItem item, bool replaceIfExists) { ArgumentValidator.EnsureArgumentNotNull(item, "item"); var key = KeyExtractor(item); ArgumentValidator.EnsureArgumentNotNull(key, "KeyExtractor.Invoke(item)"); RegisterOperation(4); WeakEntry entry; if (items.TryGetValue(key, out entry)) { var pair = entry.Value; if (!replaceIfExists) { if (pair.Key != null && pair.Value != null) { return(pair.Value); } } if (pair.Key == null) { items.Remove(key); entry.Dispose(); } } entry = new WeakEntry(key, item, trackKeyResurrection, trackItemResurrection); items[entry] = entry; return(item); }
public void Test_WeakEntry_Equals() { var viewModel = new TestViewModel(); var viewModel2 = new TestViewModel(); var weakEntry = new WeakEntry("Text1", viewModel, "Name"); var weakEntry1 = new WeakEntry("Text1", viewModel2, "Name"); var weakEntry2 = new WeakEntry("Text2", viewModel, "Name"); var weakEntry3 = new WeakEntry("Text1", viewModel, "Age"); var weakEntry4 = new WeakEntry("Text1", viewModel, "Name"); var weakEntry5 = new WeakEntry(string.Empty, viewModel, "Name"); var weakEntry6 = new WeakEntry("Text2", viewModel, string.Empty); Assert.IsFalse(weakEntry.Equals(weakEntry1)); Assert.IsFalse(weakEntry.Equals(weakEntry2)); Assert.IsFalse(weakEntry.Equals(weakEntry3)); Assert.IsFalse(weakEntry1.Equals(weakEntry2)); Assert.IsFalse(weakEntry1.Equals(weakEntry3)); Assert.IsFalse(weakEntry2.Equals(weakEntry5)); Assert.IsFalse(weakEntry2.Equals(weakEntry6)); Assert.IsTrue(weakEntry1 != weakEntry3); Assert.IsTrue(weakEntry.Equals(weakEntry4)); Assert.IsTrue(weakEntry == weakEntry4); }
/// <summary> /// Gets an associated object give an index of another object /// </summary> /// <param name='index'> /// The object to use as an index /// </param> public T this[object index] { get { //Get the hash code of the indexed object var hash = index.GetHashCode(); List <WeakEntry> entries; //Try to get a reference to it if (!references.TryGetValue(hash, out entries)) { //If we failed then create a new entry references[hash] = entries = new List <WeakEntry>(); } //Try to get an associated object of the right type for this //indexer/make sure it is still alive var item = entries.FirstOrDefault(e => e.weakReference.IsAlive && e.weakReference.Target == index); //Check if we got one if (item == null) { //If we didn't then create a new one entries.Add(item = new WeakEntry { weakReference = new WeakReference(index), associate = new T() }); } //Return the associated object return((T)item.associate); } }
/// <summary> /// Clears the property binding. /// </summary> /// <param name="source">The source.</param> /// <param name="target">The target.</param> /// <param name="sourceProp">The source prop.</param> /// <param name="targetProp">The target prop.</param> public static void ClearPropertyBinding(Object source, INotifyPropertyChanged target, string sourceProp, string targetProp) { WeakEntry entry = new WeakEntry(source.GetType(), target.GetType(), sourceProp, targetProp); Delegate setAction = GetExpressionAction(entry, source, true); WeakSource.UnRegister(source, setAction, targetProp); }
/// <summary> /// Indicates whether this instance and a specified object are equal. /// </summary> /// <param name="obj">Another object to compare to.</param> /// <returns> /// true if <paramref name="obj"/> and this instance are the same type and represent the same value; otherwise, false. /// </returns> public override bool Equals(object obj) { WeakEntry entry = (WeakEntry)obj; return((this.SourceType == entry.SourceType) && (this.TargetType == entry.TargetType) && (this.SourceProp == entry.SourceProp) && (this.TargetProp == entry.TargetProp)); }
/// <summary> /// Gets the expression action. /// </summary> /// <param name="entry">The entry.</param> /// <param name="source">The source.</param> /// <param name="createNew">if set to <c>true</c> [create new].</param> /// <param name="converter">The converter.</param> /// <returns></returns> private static Delegate GetExpressionAction(WeakEntry entry, object source, bool createNew, IDataConverter converter = null) { Delegate action = null; if (_expressionSources.ContainsKey(entry)) { action = _expressionSources[entry]; } else if (createNew) { ///// Code of the below Expression Tree //////////////////////////////// //if (converter != null) //{ // target.Property = converter.Convert(source.Property, parameter); //} //else //{ // if (target.Property.GetType() == source.Property.GetType()) // { // target.Property = source.Property; // } // else // { // throw new InvalidOperationException("The property type between binding source and target does not match, please use IDataConverter to do custom convert."); // } //} ////////////////////////////////////////////////////////////////////////// //Set Property var prop = entry.SourceType.GetProperty(entry.SourceProp); var paraObj = Expression.Parameter(entry.SourceType); //Get Property var targetProperty = entry.TargetType.GetProperty(entry.TargetProp); var paraTarget = Expression.Parameter(entry.TargetType); var getter = Expression.Property(paraTarget, targetProperty); //Combine Expression boy; var paraConvert = Expression.Variable(typeof(IDataConverter)); var paraParameter = Expression.Variable(typeof(object)); boy = Expression.IfThenElse( Expression.NotEqual(paraConvert, Expression.Constant(null)), Expression.Call(paraObj, prop.GetSetMethod(), Expression.Convert(Expression.Call(paraConvert, typeof(IDataConverter).GetMethod("Convert"), Expression.Convert(getter, typeof(object)), Expression.Convert(paraParameter, typeof(object))), prop.PropertyType)), Expression.IfThenElse( Expression.Equal(Expression.Constant(prop.PropertyType, typeof(Type)), Expression.Constant(getter.Type, typeof(Type))), Expression.Call(paraObj, prop.GetSetMethod(), Expression.Convert(Expression.Convert(getter, typeof(object)), prop.PropertyType)), Expression.Throw(Expression.Constant(new InvalidOperationException( "The property type between binding source and target does not match, please use IDataConverter to do custom convert."))))); action = Expression.Lambda(boy, paraObj, paraTarget, paraConvert, paraParameter).Compile(); _expressionSources.Add(entry, action); } return(action); }
/// <summary> /// Sets the property binding. /// </summary> /// <param name="source">The source.</param> /// <param name="target">The target.</param> /// <param name="sourceProp">The source prop.</param> /// <param name="targetProp">The target prop.</param> /// <param name="notify">if set to <c>true</c> update immediately.</param> /// <param name="converter">The converter.</param> /// <param name="parameter">The converter parameter.</param> public static void SetPropertyBinding(Object source, INotifyPropertyChanged target, string sourceProp, string targetProp, bool notify = true, IDataConverter converter = null, object parameter = null) { WeakEntry entry = new WeakEntry(source.GetType(), target.GetType(), sourceProp, targetProp); Delegate setAction = GetExpressionAction(entry, source, true, converter); WeakSource wSource = WeakSource.Register(source, target, setAction, targetProp, converter, parameter); if (notify) { wSource.NotifyPropertyChanged(target, targetProp); } }
/// <summary> /// Gets the expression action. /// </summary> /// <param name="entry">The entry.</param> /// <param name="source">The source.</param> /// <param name="createNew">if set to <c>true</c> [create new].</param> /// <param name="converter">The converter.</param> /// <returns></returns> private static Delegate GetExpressionAction(WeakEntry entry, object source, bool createNew, IDataConverter converter = null) { Delegate action = null; if (_expressionSources.ContainsKey(entry)) { action = _expressionSources[entry]; } else if (createNew) { ///// Code of the below Expression Tree //////////////////////////////// //if (converter != null) //{ // target.Property = converter.Convert(source.Property, parameter); //} //else //{ // if (target.Property.GetType() == source.Property.GetType()) // { // target.Property = source.Property; // } // else // { // throw new InvalidOperationException("The property type between binding source and target does not match, please use IDataConverter to do custom convert."); // } //} ////////////////////////////////////////////////////////////////////////// //Set Property var prop = entry.SourceType.GetProperty(entry.SourceProp); var paraObj = Expression.Parameter(entry.SourceType); //Get Property var targetProperty = entry.TargetType.GetProperty(entry.TargetProp); var paraTarget = Expression.Parameter(entry.TargetType); var getter = Expression.Property(paraTarget, targetProperty); //Combine Expression boy; var paraConvert = Expression.Variable(typeof(IDataConverter)); var paraParameter = Expression.Variable(typeof(object)); boy = Expression.IfThenElse( Expression.NotEqual(paraConvert, Expression.Constant(null)), Expression.Call(paraObj, prop.GetSetMethod(), Expression.Convert(Expression.Call(paraConvert, typeof(IDataConverter).GetMethod("Convert"), Expression.Convert(getter, typeof(object)), Expression.Convert(paraParameter, typeof(object))), prop.PropertyType)), Expression.IfThenElse( Expression.Equal(Expression.Constant(prop.PropertyType, typeof(Type)), Expression.Constant(getter.Type, typeof(Type))), Expression.Call(paraObj, prop.GetSetMethod(), Expression.Convert(Expression.Convert(getter, typeof(object)), prop.PropertyType)), Expression.Throw(Expression.Constant(new InvalidOperationException( "The property type between binding source and target does not match, please use IDataConverter to do custom convert."))))); action = Expression.Lambda(boy, paraObj, paraTarget, paraConvert, paraParameter).Compile(); _expressionSources.Add(entry, action); } return action; }