Archive for the ‘Development’ Tag

VS and SVN – Ignoring user specific files

Visual studio tends to create files that you don’t usually want to keep under source control, such as generated files, user option files, and so on. To avoid having to clean up every time you try to Add files, you can tell TortoiseSVN to ignore certain file name patterns. The following is what I usually use:

**/bin bin **/obj obj *.suo

You can set these patterns in the “Global ignore pattern” text box in the main screen of the TortoiseSVN settings dialog.

AOP using PostSharp LAOS

Recently, I came across PostSharp, an excellent open source framework for .net. Among the great set of toys which it brings along is LAOS, an Aspect Oriented Programming solution which works very neatly.

Aspect oriented programming is quite a tricky subject to explain in short, so I won’t. While it’s an oversimplification, for the purposes of this post, we will just say that it is a technique where you intercept the control flow as it passes from one block to another, and attach non-default behaviour at these points.

PostSharp provides a mechanism which lets you define attributes to specify this behaviour; you can then decorate an assembly, class, method or field with these attributes. The specific methods you overload will then be triggered accordingly.

As an example, we’re going to add a logger to a method. Yes, it’s pretty boring – 99.99% of the AOP discussions on the web use this scenario as an example. However, I just want to demonstrate how to use these attributes, so no need to rock the boat yet. (If you’re feeling adventurous, visit Manageability for a couple of ideas on what else you can do with AOP).

Let’s say that we want to write a log message every time that an exception is thrown from a method. Since we’re going to use this attribute to handle something that has to do with a method, we’re going to use the OnMethodBoundaryAspect attribute as a base. Among others, this attribute exposes an OnException method, which is just what we need:


onexceptionsource.gif

Like all interception methods exposed by OnMethodBoundaryAspect, OnException accepts a MethodExecutionEventArgs parameter. This gives us access to a lot of useful fields, among others, the name of the method being executed before interception (and all its reflected details), any parameters that were passed to the method, and the full details of the exception. This is especially handy when trying to re-create an exception.

Note the value being set in eventArgs.FlowBehavior. FlowBehavior.Continue tells the application to digest the exception and go on. Not, I must say, the smartest thing to do in all cases; in fact, I’d be dead set against finishing such an intercept this way in most cases. It’s been set that way for the purposes of the example application, where I want and expect an exception to be thrown half-way.

One other possible value of FlowBehaviour which I would like to mention briefly is the Return value. This makes the intercept digest the exception in the same way as Continue, but also allows us to set the MethodExecutionEventArgs.ReturnValue property. In this way, we can return a default value after an exception.

To actually make our new attribute DO something, we have to apply it to a method. We have a number of ways we can do this. If we want, we can specifically apply the attribute to a method (the parameter in the attribute is a constructor parameter for the attribute – refer to the source code attached):

decoratedmethod.gif

We can also apply an attribute to all methods in a class:

decoratedclass.gif

Even more neatly, we can specify an expression that identifies a selection of methods within a class. For example,

decoratedclasswithtarget.gif

The named property tells the attribute that it should apply to all methods and fields in the decorated class where the name starts with “MyLogged”.

Yet another option is to specify the attribute at an assembly level… but if you plan to do that, you really should move on to the actual PostSharp documentation 😛

The source code extends some more methods from the OnMethodBoundaryAspect attribute. You will need to install PostSharp to build the code.

kick it on DotNetKicks.com

C# 3.0 – Linq queries and Implicit Types

Finally played a bit with Linq today. About time, a lot of people will say, and rightly so. Just dipping my toes right now: wrote a short console application to list all current processes running more than 5 threads (no real use – just playing).

The whole thing was pleasantly intuitive, and the script is shown in its entirety below:

 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Diagnostics; 
using System.IO;  

namespace MyFirstLinq 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            Process[] processes = Process.GetProcesses();  

            var query = 
                from process in processes 
                where 
                    process.Threads.Count > 5 
                orderby process.Threads.Count descending 
                select new { process.ProcessName, process.Threads.Count };  

            foreach (var result in query) 
                Console.WriteLine("{0} ({1} threads)", 
                    result.ProcessName, 
                    result.Count);  

            Console.ReadKey(); 
        } 
    } 
} 

While writing this, I also had a look at the implicit type declaration (the var keyword in the code) – already ran into this while talking to Marlon the C# Monk a few days ago (thanks again for taking the time to explain stuff – helps loads!). This form of declaration looks extremely handy – you get the benefits of strongly typed return values, without the hassle of having to write several small classes that are unlikely to be used anywhere else, ever (Annoying, but has my vote for the lesser of two evils – using object arrays for return values is messy).

According to MSDN, implicit types can only be used within the method scope. This makes sense, since if you’re going to start passing them around, you will probably need to declare a proper class for their values anyway.

LuaInterface

While having a beer with an old friend yesterday, we started discussing the use of scripting languages in applications. Having seen a number of .net applications with embedded Lua scripting engines, I suggested that he look at LuaInterface, with the disclaimer that I hadn’t used it much myself.

Having nothing better to do this afternoon, I decided to download the whole thing again (the last version I’d downloaded had languishing in my download folder for about 10 months, and was probably out of date, if I could find it in the first place) and have a go at it. Attached are the results of my messing around. It’s by no means a best practice guide – or even a good practice guide, for that matter – but it looks like it’s working.

Getting lua to work in .net is simple enough; add a reference to luainterface.dll and put the luanet and lua51 dlls somewhere accessible to your application. In my case I added them as content in my VS project, and set the copy mode to “Copy Always”.

To initialise a scripting context, create a new instance of LuaInterface.Lua, which is as simple as:

LuaInterface.Lua m_ScriptingEngine = new LuaInterface.Lua();

To expose a .net object to the scripting engine, use the engine’s indexer, like so:

ScriptingEngine[“winform”] = this;

this allows the scripts to access the object and it’s properties as follows:

winform.Text = “Title Goes Here”

The lua syntax to call a method from a script is <object>:<method>(parameters) –

winform:Close()

The scripts can also access and create .net types, such as forms and buttons. The assemblies and the types must be registered first, as follows:

— Reference the .Net assemblies.
luanet.load_assembly(“System.Windows.Forms”)

— Import the specific types.
Menu = luanet.import_type(“System.Windows.Forms.MainMenu”)
MenuItem = luanet.import_type(“System.Windows.Forms.MenuItem”)

I’ve uploaded my example project. Nothing groundbreaking, but it may be useful for anyone who’s still testing the waters on this.

Further reference

Lua Reference Manual
Lua Home