Thursday, June 18, 2009

Just got myself NDepend license!

Got myself NDepend pro license from Patrick Smacchia (lead dev). Patrick, thanks alot! ;)

In short NDepend is code base analyzer which might reveal many weak links in your solution and discover many ways to improve overall structure.

I'm going to post my finding about its features while exploring this tool.

P.S. There are alot of learning demos and screenshots on official site you might want to check.

Strongly typed mapping

Often there is a need to map some properties on of class to properties of another class or columns in DB. There might be few ways to do that. The most popular ways are via code or via xml files. While working on my sharepoint-lists-to-objects mapper I had to create some way to map class properties to sharepoint fields and decided to go with code implementation. So I'm going to talk how to do that via code file in strongly typed manner.

Lets say I have a class
public class MyClass
{
public int MyProperty{get;set;}
}

and I want to map property in strogly-typed manner. So instead of typing
MapField("MyProperty", "ColumnName");

I want to have
MapField(x=>x.MyProperty, "ColumnName");

This gives a nice opportunity to refactor, as when renaming MyProperty to something else you will rename it in the mapping as well (though R# can do that for you as it can search literals with property name when renaming a property).

So we need to determine what's the name of property we're passing and also might be interested in it's type.
MapField method should have this signature to work
public void MapField(Expression<Func<MyClass, object>> expression, string columnName)
{
//get field/property name and type from expression
}


Now we have to parse that linq expression. To get required info I've wrote a class with following interface
public interface ILinqExpressionReader<T>
{
string GetFieldOrPropertyNameFromBodyOfExpression(Expression<Func<T, object>> expression);
Type GetFieldTypeFromBodyOfExpression(Expression<Func<T, object>> expression);
}


and here is the implementation:
public class LinqExpressionReader<T> : ILinqExpressionReader<T>
{
public string GetFieldOrPropertyNameFromBodyOfExpression(Expression<Func<T, object>> expression)
{
var memberInfo = GetMemberInfoFrom(expression);
return memberInfo.Name;
}

private static MemberInfo GetMemberInfoFrom(Expression<Func<T, object>> expression)
{
MemberInfo member;
if (expression.Body.GetType() == typeof(UnaryExpression))
{
var unaryExpression = (UnaryExpression)expression.Body;
if (IsMemberExpression(unaryExpression.Operand))
{
member = ((MemberExpression)unaryExpression.Operand).Member;
}
else { throw new ArgumentOutOfRangeException("expression", "Should use the following syntax: x => x.PropertyName (or x => x.FieldName)"); }
}
else if (IsMemberExpression(expression.Body))
{
member = ((MemberExpression)expression.Body).Member;
}
else { throw new ArgumentOutOfRangeException("expression", "Should use the following syntax: x => x.PropertyName"); }
return member;
}
private static bool IsMemberExpression(Expression expression)
{
return expression.GetType() == typeof(MemberExpression);
}

public Type GetFieldTypeFromBodyOfExpression(Expression<Func<T, object>> expression)
{
var memberInfo = GetMemberInfoFrom(expression);
switch (memberInfo.MemberType)
{
case MemberTypes.Property:
return ((PropertyInfo)memberInfo).PropertyType;
case MemberTypes.Field:
return ((FieldInfo)memberInfo).FieldType;
default:
throw new Exception("Cannot get types for anything but Properties and Fields");
}
}
}


Implementation uses reflection to get info that is required. Also works fine with properties or fields of Enum type.

Monday, June 15, 2009

Resharper top 5 features

Resharper has tons of ideas that can significantly improve your performance in Visual Studio making it an essencial tool for any developer who ever used it.



I wanna share what I find the most useful, so without further delay

1. Quick "goto" context menu

Where is this function used? How does the class of this variable look like? What is the implementation of this interface method? All of this questions lead to a single shortcut [Ctrl+`] It opens context menu with appropriate gotos.



2. Quick navigate to Type/Filename by name.

What? More navigation rutine? Well couldn't live without this in any mediocre to large scale solution. It's actually becomes very natural way to navigate around in time, you'll forget about forest of files in solution explorer. It is possible to navigate to class, to file and to class member by name with use of [Ctrl+T] (for types) and [Ctrl+Shift+T] (for files). Just press shortcut and type few first letters. Note that wildcards are supported as well.


3. Generation of rutine code.

[Alt+Ins] pops up a menu for fast constructor/property creation. Just hit this combo, select operation, few specifications of what you really want and you are done.



4. Reformat code

While working with source files it becomes pretty messy over time, you have public methods mixed up with private, field declarations all over the place, etc. And since you must implement features fast you don't have much time to clean up visual aspects of code. However with resharper it's just the matter of issuing a single command named full clean up - [Ctrl+E, Ctrl+C] (you might create lesser jobs too). It will move everything around to match the pattern of file layout you provide, add this. qualifiers and do some other nice stuff to keep your code well styled. Pattern should be shared among teammates to keep considtent look of source files.

5. Duplicate code. [Ctrl+D] is very nifty when it comes to duplicating. Put a cursor on a line you'd like to dup and just press Ctrl+D. Hidden benefit of this that it doesn't even touch your clipboard! (so everything in buffer stays) Duplication works horizontally too, just select a piece of line and dups will be created to the right.

6. Beyond that

Resharper extends refactorings supported by VS. Extract method [Ctrl+M] and Introduce variable [Ctrl+V] are the most commonly used by me. There are also tons of other useful refactorings waiting for you.

Tuesday, June 9, 2009

Working efficiently with sharepoint lists

A very nice guide on this topic can be found here:
http://www.infoq.com/articles/SharePoint-Andreas-Grabner

Author gives suggestions how to greatly reduce roundtrips to content database and reviews typical scenarios with really large lists.

Sunday, June 7, 2009

Need code formatting for blog or wiki?

http://formatmysourcecode.blogspot.com/ 
has a nice webscript that generates HTML for your piece of code like this:

Console.WriteLine("Hello world");

Easy component registration for Windsor Container

If you are tired of forests of declarations for WindsorContainer you might find this do a trick for you:
var container = new WindsorContainer();
container.Register(AllTypes.Pick()
.FromAssembly(Assembly.GetExecutingAssembly())
.WithService
.FirstInterface());
This piece of code will search all types within running assembly and register them in container.

Implementing AOP logging with windsor container

Long time no see :) Today I'm going to describe how to create some AOP functionality based on attributes and we'll see how to implement a very common task - logging with attributes. The same way you can implement audit, OpsDB writes, security, caching and so on, whatever you will want to.

So let's head on and write a logger:
    public static class Logger
{
private static readonly List<string> _logs = new List<string>();
public static void Log(string logMessage)
{
_logs.Add(logMessage);
}

/// <summary>
/// Returns a readonly collection of log messages
/// </summary>
public static IList<string> Logs
{
get
{
return _logs.AsReadOnly();
}
}

public static void CleanWholeLog()
{
_logs.Clear();
}
}


And now the class we're going to use to test our logging, lets start with something really simple:
    [LoggedClass]
public class Calculator
{
[LoggedMember]
public virtual int AddWithFullLogging(int a, int b)
{
return a + b;
}
}

Now we want our attributes to work for us (Im not posting attributes code to spare some space as they are just empty classes inherited from Attribute). We would like to log parameters and return values of this method.

Lets head on with a unit test:
    [TestFixture]
public class When_calling_add_of_calculator
{
private const int FIRST_OPERAND = 2;
private const int SECOND_OPERAND = 3;
private const int RESULT = 5;
private readonly Calculator _calculator = ObjectFactory.GetCalculator();

[TestFixtureSetUp]
public void TestFixtureSetUp()
{
Logger.CleanWholeLog();
this._calculator.AddWithFullLogging(FIRST_OPERAND, SECOND_OPERAND);
}

[Test]
public void Both_parameters_and_return_value_get()
{
Assert.That(Logger.Logs.Count, Is.EqualTo(2));
}

[Test]
public void Parameters_are_logged_correctly()
{
var expectedParametersLogMessage = "Calculator.AddWithFullLogging method call. Parameters: :firstParam, :secondParam";
expectedParametersLogMessage = expectedParametersLogMessage.Replace(":firstParam", FIRST_OPERAND.ToString());
expectedParametersLogMessage = expectedParametersLogMessage.Replace(":secondParam", SECOND_OPERAND.ToString());
Assert.That(Logger.Logs[0], Is.EqualTo(expectedParametersLogMessage));
}

[Test]
public void Return_value_is_logged_correctly()
{
var expectedReturnValueLogMessage = "Calculator.AddWithFullLogging finished call. Return value: :returnValue";
expectedReturnValueLogMessage = expectedReturnValueLogMessage.Replace(":returnValue", RESULT.ToString());
Assert.That(Logger.Logs[1], Is.EqualTo(expectedReturnValueLogMessage));
}
}

We clear whole log before tests and then make a call to add function. Then we expect three things to happen: 
  1. logger has 2 new entries - one for parameters and one for return value
  2. parameters are logged correctly
  3. return value is logged correcly

We're using object factory to create calculator for us. This is needed, because otherwise we wont be able to attach interceptors to its methods.
Here's the code for ObjectFactory class:
    public static class ObjectFactory
{
private static WindsorContainer _container;
private static void Init()
{
if (_container == null)
{
_container = new WindsorContainer();
_container.AddFacility("LoggingFacility", new LoggingFacility());
_container.Register(Component.For(typeof(Calculator)));
}
}
public static Calculator GetCalculator()
{
Init();
return _container.Resolve<Calculator>();
}
}

It registers calculator in container and just before that it adds Logging facility which will be intercepting registrations and add interceptors if it will find proper attributes.

Ok, so now we have it all setup lets proceed with implementation of our logging facility. In our case we would like to add logging interceptor to every method tagged with [LoggedMember] within the class tagged with [LoggedClass].
    public class LoggingFacility : AbstractFacility
{
protected override void Init()
{
Kernel.AddComponent("LoggingInterceptor", typeof(LoggingInterceptor));
Kernel.ComponentModelBuilder.AddContributor(new LoggingContributor());
}
}



    public class LoggingContributor : IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel, ComponentModel model)
{
if (model.Service.GetCustomAttributes(true).OfType<LoggedClassAttribute>().Count() == 1)
{
if (ServiceHasNonVirtualMethodsMarkedWithLoggedMemberAttributes(model))
{
throw new Exception("Cannot use LoggedMember attribute on nonvirtual members");
}
model.Interceptors.Add(new InterceptorReference(typeof(LoggingInterceptor)));
}
}

private static bool ServiceHasNonVirtualMethodsMarkedWithLoggedMemberAttributes(ComponentModel model)
{
return model
.Service
.GetMethods()
.Where(x => x.GetCustomAttributes(true)
.Where(y => y.GetType() == (typeof(LoggedMemberAttribute))).Count() == 1
&& !x.IsVirtual ).Count() > 0;
}
}

Lets run through the code. First we are defining our facility. It adds contributor to our model plus it registers interceptor that intercept calls and give logger a call. 
Then we difine contributor that checks if our service (in this case Calculator class) is tagged with [LoggedClass] attribute. If it is we're checking that every member with [LoggedMember] attribute is virtual, because we cannot intercept nonvirtual method calls thus making attribute not really working when used with nonvirtual members.
If all conditions are met we're adding logging interterceptor to method calls of calculator.

Now the easy part, we just have to implement interceptor:
    public class LoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (invocation.Method.GetCustomAttributes(true).Where(x => x.GetType() == typeof(LoggedMemberAttribute)).Count() > 0)
{
Logger.Log(GetParamsMessageFor(invocation));
invocation.Proceed();
Logger.Log(GetReturnValueMessageFor(invocation));
}
else
{
invocation.Proceed();
}
}

private static string GetReturnValueMessageFor(IInvocation invocation)
{
var message = ":methodNameWithClassSpecifier finished call. Return value: :returnValue";
message = message.Replace(":methodNameWithClassSpecifier", invocation.TargetType.Name + "." + invocation.Method.Name);
message = message.Replace(":returnValue", invocation.ReturnValue.ToString());
return message;
}

private static string GetParamsMessageFor(IInvocation invocation)
{
var message = ":methodNameWithClassSpecifier method call. Parameters:";// :firstParam, :secondParam";
message= message.Replace(":methodNameWithClassSpecifier", invocation.TargetType.Name + "." + invocation.Method.Name);
if (invocation.Arguments.Length != 0)
{
message = AddInvocationArgumentsToMessage(message, invocation);
}
return message;
}

private static string AddInvocationArgumentsToMessage(string message, IInvocation invocation)
{
message += " " + invocation.Arguments[0];
foreach (var argument in invocation.Arguments.Skip(1))
{
message += ", " + argument;
}
return message;
}
}

Note that interceptor checks if called method has [LoggedMethod] attribute, else it would log any virtual method call (even one without this attribute).