Archive for the '.NET' Category

Sep 30 2007

Really Simple Dependency Injection

Published by under .NET,Programming

Having just started a new job I find it interesting to see the way that the other developers I’m working with do things. One of the things I found in the code was for doing dependency injection. I’m not going to analyse that code as but what I will say is that I managed to replace 10 lines of code with just 3.

Without further ado here is the C# code:

public static T Get<T>() where T : class
{
string implName = Program.Settings[typeof(T).Name].ToString();
object concrete = Activator.CreateInstance(Type.GetType(implName));
return (T)concrete;
}

So what can you do with this code? Well, the way it is written means that you can create an object, the class of which is defined in a configuration file. This allows you to program to an interface but decide the concrete class in the configuration file. The method above will find the class defined for the interface being passed in, create an object of that type and return the object cast to the type of the interface.

The code used to call the method:
IPlugin plugin = PluginFactory.Get<IPlugin>();

plugin.OutputMessage("hello, world!");

The definition in the config file:
<setting name="IPlugin" serializeAs="String">
<value>GrinGod.Dependency.PluginTwo.PluginTwo,GrinGod.Dependency.PluginTwo</value
</setting>

I’m sure I haven’t explained terribly well, so I’ve thrown together a simple example that you can download. I should point out that this code a very simple example of dependency injection, it doesn’t handle passing values to the constructor of the object being instantiated, although it would be simple to add that. Also, the example I have included statically links to the two plugin assemblies, this could be changed such that the plugin assemblies are dynamically loaded using Assembly.Load()

If you want a more fully featured implementation of dependency injection you should check out the Spring.Net framework.
kick it on DotNetKicks.com

Technorati Tags: , , ,

3 responses so far

Aug 09 2006

Environment NewLine Warning

Published by under .NET

I just found a site (via dotnetkicks.com) that is advocating the use of Environment.NewLine.

I would agree that it is good to go with the use of Environment.NewLine as it adds an extra layer of platform independance, i.e. you don’t need to worry about whether to use \r\n or just \n, and you don’t need to worry so much about what happens when you port the code from one .Net language to another. It isn’t however the answer to all problems.

Environment.NewLine only answers the problem of new line on the machine that it is running on. Where you may still run into problem is when you create a file using Environment.NewLine and then move the file to another platform. This is an age old problem and I don’t have a solution for it, just that you should be under no illusion that Environment.NewLine will solve this problem.

No responses yet

Feb 01 2006

Double Imprecision In .Net

Published by under .NET

I’ve spouted on about this previously on my blog but I thought it was about time I posted some code that demonstrates some of the problems we’re up against. The problem seems to be that under certain circumstances the .Net Double data type loose its precision and gives you a number that you weren’t expecting. The chances are that the error will be out by 0.00000000000001, but that might be enough to cause an error.

The simplest way to prove this error is with a simple loop:

Dim x As Double = 0.00
While (x < 7.00)
    Console.Writeline(x)
    x += 0.01
End While

What you would normally expect is a linear progression from 0.00 to 7.00:

0.00
0.01
...
6.09
7.00

However, when the code is run you will find that somewhere in the output is some results like this:

2.28
2.29
2.29999999999999
2.30999999999999

This, as I am sure you will agree, is an unexpected result and could result in errors. If you try this exercise again but using Decimal instead of Double you will find that you get the results you expect. I’m sure there are people out there that will say that all you need to is simple rounding to get rid of the error. Sorry, but it doesn’t quite work like that and the following code will prove it:

Dim x As Double = 0.00
Dim y As Decimal = 0.00
While (x < 7.00)
    If (Math.Round(x) = Math.Round(y)) Then
        Console.Writeline("Error found")
    End If
    x += 0.01
    y += 0.01
End While

If you run this could you should get at least one error message, and probably more.

Is there a solution to this problem? Of a sort, yes. I have found that using the Decimal data type does not give the same rounding problems. Decimal also solves problems that I have had in the past with the Math.Floor() function. However, several people have told me that using the Decimal data types does incur a slight memory cost over using the Double data type. The question you need to ask yourself is “What is more important: memory or precision?“. Personally I now always use the Decimal data type. Maybe one day I’ll get around to doing some benchmarks to find out if there is a performance hit when using Decimal rather than Double… But that’s a job for another day.

3 responses so far

Jan 10 2006

Playing a wav resource in VB.NET 2.0

Published by under .NET

This is a follow-up to my previous post “Playing a wav from a resource in VB.Net“.  The previous post was how to get it working in VB.Net for the .Net Framework 1.1.  In the .Net Framework 2.0, Microsoft has been kind and provided a System.Media namespace in the core System.dll.

I happened across this file quite by accident but it seems that it will greatly simplify the code that was required for .Net 1.1.  The code for .Net 2.0 looks something like:

Imports System
Imports System.Media
Imports System.Resources
Imports System.Reflection
Imports System.IO

Public Class Sound
    Public Shared Sub PlayWavResource(ByVal wav As String)

        ' get the namespace
        Dim strNameSpace As String = Assembly.GetExecutingAssembly()_
                                    .GetName().Name.ToString()

        ' get the resource into a stream
        Dim resourceStream As Stream = Assembly.GetExecutingAssembly()_
                                     .GetManifestResourceStream(strNameSpace + "." + wav)
        If resourceStream Is Nothing Then Exit Sub

        With New SoundPlayer(resourceStream)
            .PlaySync()
        End With
    End Sub
End Class

As you can see we no longer require the calls to the Win32 API. Whilst this may not mean much to the average Joe Bloggs, it is rather important. It means that we can now play wavs from a resource stream without breaking out of managed .Net code…. I knew you’d be excited by that!!!

Note: I haven’t tested this code yet. This is only code dervied from looking through the Object Browser in Visual Studio 2005.  If you copy and paste this code you will also need to re-type the single and double quotes as WordPress screws them up.

No responses yet

Nov 29 2005

File System Alert

Published by under .NET

For a project that I’m working on we’ve recently switched from using the .Net Framework 1.1 to using the .Net Framework 2.0. Whilst .Net 2.0 does have some nice features (Generics, System.Management, XHTML compilance in ASP.Net, refactoring tools in VS2005) there are also some problems with it.

One of the problems we have had is that, for no apparent reason, our IIS server will create a memory dump. So far there doesn’t seem to be any correlation between user activity and the dump files being created. Due to the fact that the dump files and event messages generated by IIS are less than helpfull – thats putting it mildly – I resorted to Microsofts latest debug tools, DebugDiag, to help me sort out what the problem could be.

The only trouble is that I don’t have all day to sit around waiting for DebugDiag to create its more informative memory diagnostic dumps, I’ve got work to be getting on with. What I needed is a piece of software that would inform me when file in the DebugDiag output folder is created. The .Net framework provides a component that can do just such a task called the FileSystemWatcherunfortunately it doesn’t have an interface. So, as any programmer would to when faced with a task, I went ahead a created a neat little software tool that sits in my system tray and alerts me when files in the DebugDiag folder are created.

However, I didn’t stop there. Why should I create a tool with such a narrow market. Surely if I want to watch one folder for new files, at some point I’ll need to watch other folders, maybe I’ll need to watch for other events such as changed and deleted files. Enter File System Alerts. In this tool users can create any number of watches with varying settings. Users can be notified by a system tray alert, the alert window being brought to the foreground and a log file being created.

THe latest version of the installer can be downloaded from my Downloads page. At time of going to press the latest version is 1.0.2159.28024.

No responses yet

Oct 28 2005

Suspect Rounding In .Net

Published by under .NET

For the past week (might be a slight exageration) I have been working on two rather complex and long winded calculations for a certain project that I am working on. I have been given a set of data to run through the calculations and a list of expected results. Unfortunately I have been receiving some rather unexpected rounding results and as soon as I manage to fix the rounding for some of the dataset it seems to throw out the results for other items in the dataset.

Unfortunately I am unable to step through the code as it is running the calculation and (until late on Friday) I was only able to output one result value. As a result I debugging has been a rather slow and laborious process. On Friday I implemented a debugging system that let me not only output a final result but also log various values throughout the calculation process.

Today I finally I managed to track down the round problem to the .Net Math.Floor() function.

From the MSDN library:

Returns the largest whole number less than or equal to the specified number.

[Visual Basic]
Public Shared Function Floor(ByVal d As Double) As Double

Parameters
d
A number.

Return Value
The largest whole number less than or equal to d. If d is equal to NaN, NegativeInfinity, or PositiveInfinity, then that value is returne

The code that was causing me problems was the following:

Public Function Truncate(number As Double, places As Integer) As Double
    Dim temp As Integer = Math.Floor(number * Math.Pow(10,places))
    Return temp / Math.Pow(10,places)
End Function

What this code does, is take a floating point number and truncate it to a user specified number of decimal places. For example Truncate(125.12542, 2) should give a result of 125.12. It should also be possible to truncate to 0 decimal places using, for example, Truncate(125.12542, 0) should give a result of 125.

The trouble I was getting, however, was that I was calling Truncate(1001.010, 2) and I was getting a result of 1001.00 when the result should have been 1001.01. As you can imagine, when you are working with financial calculations even a penny out is far from acceptable…. all calculations have to be exact. So this problem had to be resolved.

I’m not about to give you a run down of the whole debugging process that I had to go through as it took several days and a lot of caffine and stress. But in the end I tracked to the problem to being the fact that I had used the Double vairable type. For some reason, which I’m still not entirely aware of, the is some odd rounding when rounding Doubles. These issues seem to disappear if you use variables of type Decimal. So I spent a whole day going through my code replacing all instances of Double with Decimal.

Now that I have completed that all my code is now producing the correct results. If only Microsoft had made these issues more clear in their documentation I might have saved myself several days work and a lot of stress.

2 responses so far

May 25 2005

MojaviBuilder Under Mono?

Published by under .NET,MojaviBuilder

Having subscribed to the MWF blog I noticed today that they have finally posted a new entry.

Whilst this in itself isn’t too interesting, some of the information in the entry is interesting. Firstly, the MWF (Microsoft Windows Forms) project for Mono is now up to 98% complete. Most of the basic controls are now complete.

The second interesting piece of information is that you can now get a Live CD for mono. The CD is freely available as an ISO which can be downloaded directly via HTTP or via BitTorrent (see www.mono-live.com).

The upshot of all this is that hopefully MojaviBuilder will now run under Mono. I have downloaded the ISO via BitTorrent which I’ll burn to CD when I get home and then have a go and running MojaviBuilder. If it does run then I’ll know I can go continue developing MojaviBuilder in .NET 1.1 safe in the knowledge that I can be run under Windows, Linux, and MacOS.

2 responses so far

Apr 29 2005

Application Design & Plugins

Published by under .NET

I’m currently starting to design a new application in VB.NET. Well, actually its a re-working of a previous application I’ve created, MojaviBuilder. This time, however, I’m actually taking the time to design the application before I start writing it. The previous version sort-of evolved as I was writing it and as a result the code is a bit chaotic.

One thing I would like I the new version is to have a plugin architecture so that users can extend the functionality of the application, e.g. add a code editor to change the file template. The trouble I have though, is that at this point in the design I can’t see which areas of the application will need to be extended with plugins.

It would be nice to be able to have different object models for the different Mojavi versions as plugins, however I see that as being rather central to the application. This quandry has left me with three possible solutions:

  1. I leave out the plugin architecure at this time and re-work it into the application at a later date.
  2. I try and second guess how users might want to use plugins in the future and do a best guess architecture from the beginning.
  3. I say “to hell with it”, create the application as a plugin controller and write the actual workings as plugins for the controller.

My initial thoughts were to go with option 2 and try to second guess what the users would want. I can think of a couple of possible plugins but don’t want to have that functionality in the main application, therefore I could write an architecture to facilitate those plugins.

I am now, however swinging towards the central plugin controller option. This I fear may take a large amount of time to create and optimise so that it runs efficiently, so I think I am therefore being driven towards option 1: write MojaviBuilder as I think that average user would require it, look back at it in the future to see how a plugin architecture could be retro-fitted. Whilst following option 1 I would also be looking at how the plugin-controller could be created.

No responses yet

Jan 26 2005

VB.NET: MsgBox() or MessageBox.Show()?

Published by under .NET

I’m currently using VB.NET as my main language because thats what my project at work requires. But having come from programming in VB6 I was just wondering if I’m using some of the old VB6 constructs and functions just because they are still there or because they really are the best way of doing things in VB.NET.
Continue Reading »

12 responses so far

Jan 21 2005

Playing a wav from a resource in VB.NET

Published by under .NET

This is a little code snippet that will allow you to play wav files that are embedded in your VB.NET exe. This code is based on a C# class by Peter A. Bromberg that I found on this page.

I had to do a little reworking to get it to play with VB.NET. ANd my VB code probably isn’t the neatest way that it could be done… but it works.

Imports System
Imports System.Runtime.InteropServices
Imports System.Resources
Imports System.IO

Public Class Sound

	Private Shared SND_ASYNC As Integer = 1
	Private Shared SND_MEMORY As Integer = 4

	Declare Function PlaySound Lib "winmm.dll" Alias "PlaySoundA" (ByVal lpszName As Byte(), ByVal hModule As Integer, ByVal dwFlags As Integer) As Integer

	Public Shared Sub PlayWavResource(ByVal wav As String)

		' get the namespace	
		Dim strNameSpace As String = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name.ToString()

		' get the resource into a stream
		Dim resourceStream As Stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(strNameSpace + "." + wav)
		If resourceStream Is Nothing Then Exit Sub
	
		' bring stream into a byte array
		Dim wavData As Byte()
		ReDim wavData(CInt(resourceStream.Length))
		resourceStream.Read(wavData, 0, CInt(resourceStream.Length))

		' play the resource
		PlaySound(wavData, 0, SND_ASYNC Or SND_MEMORY)
	End Sub
End Class

do to user this code is create a new VB.NET class file and paste this code in. When you want to play a wav you must include the wav file in your project as an embedded resource and use the following (replacing the name of the wav file to be played):

Sound.PlayWavResource("chimes.wav")

Please note that the Sound class must be in the same assembly as the the wav file.

Update: Please copy the source code and paste it into a texteditor to read it as the code has been broken onto multiple lines on this page by my blog stylesheet.

Update 2: Yes I know its got the same comments as the page I referenced above. Give me a break, its 8pm on a Friday and I’m still at work. What more do you want? For me to translate the bible into Haxxor?

Update 3: I’ve just corrected a couple of errors in the above code (removed a > and removed an extra End If)

5 responses so far

« Prev - Next »