Reflection, drive me crazy!

Zipping my code to the maximum has made me take the hard to understand but powerful way of .NET Reflection.

This crazy ViewModel plays with DataWrappers (a concept from the Cinch Framework by Sacha Barber). I modified the framework to add a feature that makes it even better in a reflection-wise approach.

Take a look at this method of the ViewModel:

private void DataWrapperOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
        {
            var dataWrapper = (DataWrapperBase) sender;

            if (!dataWrapper.IsValid)
            {
                return;
            }

            var dataValue = dataWrapper.GetPropertyValue("DataValue");
            var dataWrapperName = dataWrapper.ParentPropertyChangeArgs.PropertyName;

            var targetPropertyName = GetTargetPropertyName(dataWrapperName);

            try
            {
                TargetItems.SetPropertyToAll(targetPropertyName, dataValue);
            }
            catch (TargetException ex)
            {
                Debug.Write(ex);
            }
        }

It takes the DataWrapper, its current DataValue and its name. Then, translates (optionally) the name of the property (the equivalent property in the actual object of the model) and applies the value to the analogous property of each target item (TargetItems is an IEnumerable).

It can be improved even more (applying value conversion because sometimes the target and source properties may not be of the same type, for example), but it works pretty good. And the best of this is that I saved A LOT of boring cloned lines.

Hard things with Expressions (property selector)

It has been hard at least for me.

This method applies the value to the specified property of the target items:

 private static void SetPropertyToAll<T, TValue>(IEnumerable<T> targetItems, Expression<Func<T, TValue>> propertyExpression, TValue value)
        {
            if (propertyExpression.Body is MemberExpression)
            {
                var memberExpression = (MemberExpression)propertyExpression.Body;

                var propInfo = (PropertyInfo)memberExpression.Member;

                foreach (var item in targetItems)
                {
                    propInfo.SetValue(item, value, null);
                }
            }
            else
            {
                throw new InvalidOperationException("See link to the Stack Overflow question below!!");
            }
        }

And this is the original question in which I found all the information I needed in order for this to work like fine cinnamon 😉

http://stackoverflow.com/a/2789606/1025407

Good luck, Expression Boy!

Have fun. Modifying properties that are value types

Have fun. Modifying properties that are value types

Look at those remarks. Value types. Naughty boys!

If you have a property of type Point, for example, and you invoke the Offset to modify the X / Y members, you soon will realize that the original value isn’t modified. Here is why 😛

 

PointOffset Method 

Offsets a point’s X and Y coordinates by the specified amounts.

REMARKS

This operation is equivalent to adding a Point to a Vector.

Note that calling the Offset method will only have an effect if you can change the X and Y properties directly. Because Point is a value type, if you reference a Point object by using a property or indexer, you get a copy of the object, not a reference to the object. If you attempt to change X or Y on a property or indexer reference, a compiler error occurs. Similarly, calling Offset on the property or indexer will not change the underlying object.  If you want to change the value of a Point that is referenced as a property or indexer, create a new Point, modify its fields, and then assign the Point back to the property or indexer. 

Nice MultiValueConverter

If you have a MultiBinding and you want to get true when every binding evaluates to the same value, then this is four you, little pollo:

 public class AllEqualConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (!values.Any())
            {
                return true;
            }

            var first = values.First();

            var allAreTheSame = values.All(other => Equals(first, other));
            return allAreTheSame;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException("This is only mean to support conversions in One Way");
        }
    }

Self note for Interaction.Triggers

Event Triggers only work for Routed Events!

<i:Interaction.Triggers>
<i:EventTrigger EventName="ColumnResizeFinished">
<i:InvokeCommandAction Command="{Binding SetColumnSizesCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type dynamicDatagrid:DataGridEx}}, Path=ColumnBeingManipulated}" />
</i:EventTrigger>
</i:Interaction.Triggers>

I’m starting to hate the Repository pattern

What we supposedly use the Repository pattern for?

  • For querying the model?
  • For CRUD operations?
  • To have work with entities like they were already loaded in memory?
  • To not depend on underlying technologies like ORMs?

Pure junk! All those arguments could live in the 2000s, but they are now absolutely outdated!!

I’m done with that pattern. It doesn’t offer a **** and instead of this, it just adds complexity and a bunch of classes and interfaces that restrict your queries to a poor set. It’s OK that you can write your own methods in a custom repository, but as you do, it loses its maintainability and it can really get riddled with tenths of methods for each kind of query you want to get (and this really gets worse when you have to retrieve lots of different DTOs).

So, forget about this pattern if you’re getting data access seriously and start researching on new ways to do MORE, not the same or less.

Use an ORM! and don’t wrap it! if you do, you’re losing your precious time. Do you think that a change in the Database will not affect you if you wrap, and wrap, and wrap it again? HA! In the best of cases you will end up having to design 200 DTOs and 1000 different methods to access the database in a “decoupled” way.

So if you try to make an onion, good luck!