Custom business object comparer - c#

I need to implement mechanism that compares two business objects and return the list of differences (past value, new value, isDifferenceBetter).
Because not all fields of class has to be compared and one fields need to be compared with different function then the other (sometimes < is better sometimes > is better ... ) I figured out that I need to implelemnt custom attribute and give it to each field that has to be compared in this object.
This attribute must have:
- name
- delegate or sth to point to the function which would be applied for comparision (dont know how to do it so far)
So could anyone suggest me if its a good idea? Maybe any other ideas.
Using attributes I would be able to use refflection to iterate through each field with attribute and invoke needed delegate.
thanks for help
bye

See my example below.
May be, it can help you:
namespace ConsoleApplication5
{
class FunctionToCompareAttribute : Attribute
{
public FunctionToCompareAttribute( String className, String methodName )
{
ClassName = className;
MethodName = methodName;
}
public String ClassName
{
get;
private set;
}
public String MethodName
{
get;
private set;
}
}
class ComparableAttribute : Attribute
{
}
class CompareResult
{
}
[Comparable]
class ClassToCompare
{
[FunctionToCompare( "ConsoleApplication5.ClassToCompare", "MyCompareFunction" )]
public String SomeProperty
{
get;
private set;
}
public static CompareResult MyCompareFunction( Object left, Object right, String propertyName )
{
return null;//Comparsion
}
}
class Program
{
static void Main( string[] args )
{
var left = new ClassToCompare();
var right = new ClassToCompare();
var type = typeof( ClassToCompare );
var typeAttributes = type.GetCustomAttributes( typeof( ComparableAttribute ), true );
if ( typeAttributes.Length == 0 )
return;
foreach ( var property in type.GetProperties() )
{
var attributes = property.GetCustomAttributes( typeof( FunctionToCompareAttribute ), true );
if ( attributes.Length == 0 )
continue;
var compareAttribute = attributes[ 0 ] as FunctionToCompareAttribute;
var className = compareAttribute.ClassName;
var methodName = compareAttribute.MethodName;
var compareType = Type.GetType( className );
var method = compareType.GetMethod( methodName, new Type[] { type, type, typeof( String ) } );
var **result** = method.Invoke( null, new Object[] { left, right, property.Name } ) as CompareResult;
}
}
}
}

Do some search about self tracking objects and the way ORMs(like NHibernate) checking an object for dirty fields

Certainly possible but perhaps you should be thinking along more abstract terms. Maybe a pair of attributes [LowerValueIsBetter] and [HigherValueIsBetter] would enable you to express this information in a more cohesive way.

Related

Excluding an aspect from specific implementations of a generic class?

Say I have a generic class:
public abstract class MyClass<T> {
// Contents
}
How can I specify an exclude for my aspect for only certain types of T? I am adding aspects in ithe AssemblyInfo.cs, like so:
[assembly: LogMethod(AttributePriority = 0,
AttributeTargetTypeAttributes = MulticastAttributes.Public,
AttributeTargetMemberAttributes = MulticastAttributes.Public,
AttributeTargetElements = MulticastTargets.Method)]
It is not possible to apply generic arguments filtering in a declarative way. For advanced filtering of the aspect targets you can override CompileTimeValidate method on your aspect and filter programmatically.
However, even this is not going to be enough in the case you've described. Let's say you've applied the aspect to a method in MyClass<T>. At this point in compilation the T is not known yet, so it's not possible to perform the check. The concrete T is known when a field or variable of MyClass<T> is declared somewhere else in the code.
The best option I can see in your case is to make the aspect instance-scoped and validate at run-time for each instance of the target class. You can find the sample implementation of this approach below.
[PSerializable]
public class LogMethodAttribute : OnMethodBoundaryAspect, IInstanceScopedAspect
{
private bool disabled;
public override void OnEntry( MethodExecutionArgs args )
{
if ( !this.disabled )
{
Console.WriteLine( "OnEntry: {0}({1})", args.Method.Name, args.Arguments.GetArgument( 0 ) );
}
}
public object CreateInstance( AdviceArgs adviceArgs )
{
LogMethodAttribute clone = (LogMethodAttribute) this.MemberwiseClone();
Type type = adviceArgs.Instance.GetType();
if ( type.IsGenericType )
{
Type[] genericArguments = type.GetGenericArguments();
// Filter out targets where T is string.
if ( genericArguments[0] == typeof( string ) )
{
clone.disabled = true;
}
}
return clone;
}
public void RuntimeInitializeInstance()
{
}
}
class Program
{
static void Main( string[] args )
{
var obj1 = new Class1<int>();
obj1.Method1(1);
var obj2 = new Class1<string>();
obj2.Method1("a");
}
}
[LogMethod(AttributeTargetElements = MulticastTargets.Method)]
public class Class1<T>
{
public void Method1(T a)
{
}
}

Measuring relational inheritance distance between types

Does anyone know how I could (or if there is an existing algorithm) measure the relational distance between two .NET types?
By this I mean the number of 'steps' in the hierarchical tree that is required to get from object A to object B.
For example, if object A is a Button, and object B is a LinkButton, there would be 2 steps, Button -> WebControl -> LinkButton. Would I need to create my own static inheritance tree and use a path finding algorithm, or is there a way I can dynamically look at the inheritance structure of .NET to calculate the distance between two objects?
Non-generic way (also you don't have to specify parent/child explicitly):
private static int CalulateDistanceOneWay(Type firstType, Type secondType)
{
var chain = new List<Type>();
while (firstType != typeof(object))
{
chain.Add(firstType);
firstType = firstType.BaseType;
}
return chain.IndexOf(secondType);
}
// returns -1 for invalid input, distance between types otherwise
public static int CalculateDistance(Type firstType, Type secondType)
{
int result = CalulateDistanceOneWay(firstType, secondType);
if (result >= 0)
{
return result;
}
return CalulateDistanceOneWay(secondType, firstType);
}
EDIT: update to calculate cousins:
public class DistanceResult
{
public Type SharedAncestor { get; private set; }
public int FirstTypeDistance { get; private set; }
public int SecondTypeDistance { get; private set; }
public DistanceResult(Type sharedAncestor, int firstTypeDistance, int secondTypeDistance)
{
SharedAncestor = sharedAncestor;
FirstTypeDistance = firstTypeDistance;
SecondTypeDistance = secondTypeDistance;
}
}
static DistanceResult CalculateDistance(Type firstType, Type secondType)
{
var firstChain = new List<Type>();
while (firstType != typeof(object))
{
firstChain.Add(firstType);
firstType = firstType.BaseType;
}
firstChain.Add(typeof(object));
var secondChain = new List<Type>();
while(secondType != typeof(object))
{
secondChain.Add(secondType);
secondType = secondType.BaseType;
}
secondChain.Add(typeof(object));
for(var i = 0; i < secondChain.Count; i++)
{
var type = secondChain[i];
int index = firstChain.IndexOf(type);
if (index >= 0)
{
return new DistanceResult(firstChain[index], index, i);
}
}
return null;
}
You can walk through an inheritance path using Type.BaseType. For example:
public static int GetTypeDistance<T, B>(T t, B baseType)
{
if (t is B) // checking if t inherits baseType
{
int distance = 0;
Type curType = t.GetType();
while (curType != typeof(B) && curType != null)
{
distance++;
curType = curType.BaseType;
}
return distance;
}
else { throw new Exception("..."); }
}
Based on the answers from Ondrej and Bényi here are two extension methods to compute the distance from a particular type to either its (indirect) base class type or one of the interfaces implemented by it or one of its base classes.
Usage examples:
Assert.AreEqual( 4, typeof( MultiDictionary<int, int> ).DistanceTo<IEnumerable>() );
Assert.AreEqual( 4, typeof( MultiDictionary<int, int> ).DistanceTo( typeof( IEnumerable ) );
Assert.AreEqual( 2, typeof( StringReader ).DistanceTo( typeof( IDisposable ) ) );
Extension methods:
public static class ExtensionsForType
{
public static int DistanceTo( [CanBeNull] this Type current, [NotNull] Type target )
{
Contract.Requires<ArgumentNullException>( target != null );
// `root` will point to the topmost type which is implementing
// our `target` interface
Type root = current;
// search for topmost base type implementing `target` interface type
// or for the `target` base class type itself
int distance = 0;
while ( current != null && ( target.IsInterface
? current.GetInterfaces().Contains( target )
: current != target ) )
{
root = current;
current = current.BaseType;
distance++;
}
// probably the `current` type does not even derive from / implement
// the target type at all
if ( current == null ) return -1;
// if it's not an interface then we've found it in one of the base classes
if ( !target.IsInterface ) return distance;
// go one step back, because 'current' does not implement
// our target interface anymore
distance--;
// iterate interface "derivations" while the target interface is still
// in the list of implemented interfaces
Type[] interfaces = root.GetInterfaces();
while ( interfaces.Contains( target ) )
{
interfaces = interfaces.SelectMany( i => i.GetInterfaces() ).ToArray();
distance++;
}
return distance;
}
public static int DistanceTo<T>( [CanBeNull] this Type current )
{
return current.DistanceTo( typeof( T ) );
}
}

get all attributes of an overriden property

Take for example the below sample code:
public class TestMultipleAttributesAttribute : AttributeWithPriority
{
public string HelpMessage { get; set; }
}
public class Student
{
[TestMultipleAttributes(HelpMessage = "Student")]
public virtual string Name { get; set; }
}
public class SpecificStudent : Student
{
[TestMultipleAttributes(Priority = 100, HelpMessage = "SpecificStudent")]
public override string Name { get; set; }
}
Is there any way by reflection how I can get both the two instances of the TestMultipleAttributes for the same overriden property?
I tried the below code:
[Test]
public void testMultipleAttribs()
{
var property = typeof(SpecificStudent).GetProperties().FirstOrDefault(x => x.Name == "Name");
var attribList = property.Attributes; //returns none
var customAttribs = property.CustomAttributes.ToList(); //returns 1
var customAttribs2 = property.GetCustomAttributes(inherit: true);// returns 1
int k = 5;
}
One solution that came in mind is to find the property.DeclaringType, and repeating the process , and get the attributes for it. However, I don't find it an elegant way to do this and was wondering if there is a better way.
You have only one attribute named TestMultipleAttributes and you overwrote it.The attribute have more than one property (Priority and HelpMessage) its working correctly.
You can create more "really" attributes like so StudentAttribute and SpecificStudentAttribute.
I don't know...this is relatively elegant (though I'm sure I'm missing at least one special case). It should enumerate all the custom attributes on an overridden or virtual property in the inheritance chain in nearest-first order:
public static IEnumerable<Attribute> AllAttributes( PropertyInfo pi )
{
if ( pi != null )
{
// enumerate all the attributes on this property
foreach ( object o in pi.GetCustomAttributes( false ) )
{
yield return (Attribute) o ;
}
PropertyInfo parentProperty = FindNearestAncestorProperty(pi) ;
foreach( Attribute attr in AllAttributesRecursive(parentProperty) )
{
yield return attr ;
}
}
}
private static PropertyInfo FindNearestAncestorProperty( PropertyInfo property )
{
if ( property == null ) throw new ArgumentNullException("property") ;
if ( property.DeclaringType == null ) throw new InvalidOperationException("all properties must belong to a type");
// get the property's nearest "ancestor" property
const BindingFlags flags = BindingFlags.DeclaredOnly
| BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Static | BindingFlags.Instance
;
Type t = property.DeclaringType.BaseType ;
PropertyInfo ancestor = null ;
while ( t != null && ancestor == null )
{
ancestor = t.GetProperty(property.Name,flags) ;
t = t.BaseType ;
} ;
return ancestor ;
}

UnityContainer.BuildUp() - Can I make it inject new instances into properties only if these are null?

I'm deserializing a class like this one
class AClass{
[Dependency]
AnotherClass Property{ get; set; }
}
When I then BuildUp() the object I'd like Unity to create a new instance of AnotherClass only if the property is null and otherwise just perform a BuildUp on it.
Is there a simple way to achieve this?
Edit: I'm doing mvvm with wpf. The classes are view-models, I serialize them as there are some properties I want to preserve between runs and they also have some dependencies I want unity to inject. So after deserialization the nested model is already there with properties set so I don't want unity to override it with a new instance but I still want it to call InjectionMethods on it and also to resolve it normally the first time the program is run and the nested models are null.
I ended up writing a unity extension.
I could not find much documentation on how to do this so I'm not really sure about the result.
It seems to work but I have this feeling I might have written something horrible..
Anyway here's the code, improvements are welcome:
public class RecursiveBuildUpContainerExtension : UnityContainerExtension {
protected override void Initialize(){
Context.Strategies.Add( new RecursiveBuildUpBuilderStrategy( Context.Container ), UnityBuildStage.PreCreation );
}
}
public class RecursiveBuildUpBuilderStrategy : BuilderStrategy {
readonly IUnityContainer container;
public RecursiveBuildUpBuilderStrategy( IUnityContainer container ) {
this.container = container;
}
public override void PreBuildUp( IBuilderContext context ) {
if( context.Existing == null ) return;
foreach( var prop in context.Existing.GetType( ).GetProperties( ) ) {
if( ContainsType<DependencyAttribute>( prop.GetCustomAttributes( true ) ) ) {
if( prop.GetValue( context.Existing, null ) == null ) {
var value = container.Resolve( prop.PropertyType );
prop.GetSetMethod( ).Invoke( context.Existing, new[] { value } );
}
else {
var value = container.BuildUp( prop.PropertyType, prop.GetValue( context.Existing, null ) );
prop.GetSetMethod( ).Invoke( context.Existing, new[] { value } );
}
}
}
foreach (var method in context.Existing.GetType().GetMethods() ){
if( ContainsType<InjectionMethodAttribute>( method.GetCustomAttributes( true ))){
var argsInfo = method.GetParameters( );
var args = new object[argsInfo.Length];
for( int i = 0; i < argsInfo.Length; i++ ) {
args[i] = container.Resolve( argsInfo[i].ParameterType );
}
method.Invoke( context.Existing, args );
}
}
context.BuildComplete = true;
}
private static bool ContainsType<T>( IEnumerable<object> objects ){
foreach (var o in objects){
if( o is T ) return true;
}
return false;
}
}
You can write your own BuildUp method, like this:
public static void BuildUpButSkipInitializedProperties(
this UnityContainer container, object instance)
{
var registeredTypes = (
from registration in container.Registrations
select registration.RegisteredType)
.ToArray();
var injectableProperties =
from property in instance.GetType().GetProperties()
where property.GetGetMethod() != null
where property.GetSetMethod() != null
where property.GetValue(instance, null) == null
where registeredTypes.Contains(property.PropertyType)
select property;
foreach (var property in injectableProperties)
{
object value = container.Resolve(property.PropertyType);
property.SetValue(instance, value);
}
}
Usage:
var instance = new AClass();
container.BuildUpButSkipInitializedProperties(instance);
I didn't test or even compile this code, but it should pretty much do the trick. Note that since it iterates all Registrations every time and injects all properties using reflection, it might not be the fasted thing ;-)
Is there a simple way? No.
You'd need to edit the generated il, detect already existing objects... It could be done but it's in no way simple.

Checking whether a certain type is an Action delegate

I'm trying to check whether a given type is an action delegate, regardless of the amount of parameters.
The following code is the only way I know how to do this.
public static bool IsActionDelegate( this Type source )
{
return source == typeof( Action ) ||
source.IsOfGenericType( typeof( Action<> ) ) ||
source.IsOfGenericType( typeof( Action<,> ) ) ||
....
source.IsOfGenericType( typeof( Action<,,,,,,,,,,,,,,,> ) );
}
IsOfGenericType() is another extension method of mine, which does what it says, it checks whether the type is of the given generic type.
Any better suggestions?
If you are just after the delegates that have a void return type you could do the following:
public static bool IsActionDelegate(Type sourceType)
{
if(sourceType.IsSubclassOf(typeof(MulticastDelegate)) &&
sourceType.GetMethod("Invoke").ReturnType == typeof(void))
return true;
return false;
}
This would not distinguish between Action and MethodInvoker (or other void delegates for that matter) though. As other answers suggest you could examine the type name, but that kinda smells ;-)
It would help if you could clarify for what reason you want to identify Action delegates, to see which approach would work best.
static Type[] _actionTypes = new[]{
typeof(Action),
typeof(Action<>),
typeof(Action<,>),
typeof(Action<,,>),
typeof(Action<,,,>),
typeof(Action<,,,,>),
typeof(Action<,,,,,>),
typeof(Action<,,,,,,>),
typeof(Action<,,,,,,,>),
typeof(Action<,,,,,,,,>),
typeof(Action<,,,,,,,,,>),
typeof(Action<,,,,,,,,,,>),
typeof(Action<,,,,,,,,,,,>),
typeof(Action<,,,,,,,,,,,,>),
typeof(Action<,,,,,,,,,,,,,>),
typeof(Action<,,,,,,,,,,,,,,>),
typeof(Action<,,,,,,,,,,,,,,,>)
};
private static bool IsAction(Delegate d)
{
return d != null && Array.IndexOf(_actionTypes, d.GetType()) != -1;
}
This seems to work:
private static bool IsActionDelegate(this Type source)
{
var type = source.Name;
return source.Name.StartsWith("System.Action");
}
Example:
public static class Test
{
public static bool IsActionDelegate(this Type source)
{
var type = source.Name;
return source.Name.StartsWith("Action");
}
}
class Program
{
static void Main(string[] args)
{
Action<string> one = s => { return; };
Action<int, string> two = (i, s) => { return; };
Func<int, string> function = (i) => { return null; };
var single = one.GetType().IsActionDelegate();
var dueces = two.GetType().IsActionDelegate();
var func = function.GetType().IsActionDelegate();
}
}
Single and dueces are true. func is false
These are distinct types with nothing in common but their name. The only semi-reasonable shortcut I can think of:
public static bool IsActionDelegate( this Type source )
{
return source.FullName.StartsWith("System.Action");
}
Certainly not fail-safe, but whomever declares his own types in the System namespace deserves some pain and suffering.

Categories

Resources