C# 3 Automatic Properties - Are they any good?
Microsoft have gone a long way in the latest versions of .NET languages to make them more terse. They seem to have mainly done a good job in this area. Some language enhancements for the sake of less typing ensures that, in my opinion, the code becomes harder to read, but in the case of automatic properties this is not the case.
Automatic properties simply allow you to type less when defining your simple properties. So, imagine a class that contains the following:
private string mystring;
public string yourstring
{
get { return mystring}
set { mystring = value; }
}
Instead of typing this, you can simply type:
public string yourstring { get; set; }
Nothing is lost when trying to read this property. The C# compiler will automatically create a private variable but this cannot be referenced. If you really need to reference the private variable then you can always go back to longhand but it's a great way to get your properties off the ground without having to write too much code.
Ok - so some may be asking why if we are only going to get and set a property do we not use a public field instead. There are good reasons. Personally I hardly ever use public fields. Public fields are not as easy to bind to as a property and if you want to add validation (for example) then you cannot simply swap to a public property at a later date with ease.
So, automatic properties are a great way to get your properties up and running. Whilst you do have to create a get and a set (no read or write only) they provide another faster way to code that is easy to understand.
Cheers,
Rich
Extension Methods mystery
I had the pleasure of attending the MSDN roadshow up in Harrogate today. Very interesting all round I must say but I was particularly impressed with some of the new language enhancements that are soon to arrive. One particular language enhancement that caught my eye was Extension Methods.
For those that have not yet seen this new language enhancement, an extension method basically allows a developer to add a method to a utility or service layer class and then treat it in intellisense as if it were part of the object that they were servicing. Imagine having a sealed car class that you wanted to extend no further with new methods, but added a utility class that would take in a car object and clean it for you. By simply adding the "this" keyword in front of the car parameter it would now appear in intellisense as car.clean(). Great - it's now easy to know all of our service layer methods that are not part of the object.
This was presented by Microsft UK's excellent Daniel Moth. Based on my previous article on Anemic Domain Models I asked Daniel if he thought that this was Microsoft actually supporting an Anemic Domain Model. The answer was no of course. Methods can still be added to the object which is often where they belong. However, Microsoft deliberatly adding this type of support into the language does go some way to showing that moving methods out into a service or utility layer is no bad thing and that they recognise that many developers are creating utility layers instead of shoving everything into the domain objects. Hooray for Extension methods.
Cheers
Rich
SQL Search tables
Working on a small project that we have on at the moment, a site is being built. The site uses a SQL database to store basic information. In one of the tables there is (quite commonly) a varchar field in which is held names. All I needed to do was pass my database several names to search on and ensure that it performed in a pretty quick fashion. I could pass it just one name or perhaps several. This wasn't something that we would know until runtime.
Not being a SQL kinda person I was thinking of passing in the items in an XML string, parsing these using OPENXML and using a common "IN" statement or even building up a bit of dynamic SQL using the "OR" statement and then executing that. Until I was told about a handy trick to speed this up, especially as the table grows to thousands of rows.
Many (mostly DBA type people) probably already know what I'm going to say. I've kept the part where I pass in the XML string and parse it using OPENXML, however putting these items into a table variable and then joining my main table to it prooduces lightening fast results. Works like a charm.
Cheers
Rich
Anemic Domain Models
Why do I like the anemic domain model? Martin Fowler, who I have much respect for describes the anemic domain model as an anti-pattern. The anemic domain model (from now on referred to as the ADM) is the opposite to the Rich Domain Model (referred to as the RDM).
The RDM is OO purist and mixes the domain logic with the domain objects. So, for a car class, all of the car type methods would be mixed with the car domain object, which is what OO is about. Mixing behavior with traits (or methods with properties).
The ADM on the other hand mainly separates the domain logic from the domain object, leaving the domain object to be a carrier of nothing but state for the data whilst allowing a separate service layer to perform actions upon those objects. In an ADM, a person object has mainly only properties and become a "reference" object, only containing minimal numbers of methods. Service object then act as components that are able to perform actions on these objects.
However, I think that the anemic domain model has retained and in fact gained some popularity over time for a few reasons. It is true and commonly said that those that come from a data background are more likely to use an anemic domain model as data is at the core of the application for these people. However, it is not just those data modelers that favor the ADM.
The ADM allows clear boundaries between representing the state of the domain and those things that have an acting force upon it. Writing our domain model against a good set of interfaces allows us also to build a useful service layer that can act upon all sorts of domain objects.
Readability in an ADM architecture is also, IMHO an easier task facilitated by the clearer boundaries. In all probability the ADM has become more popular though not just for these reasons, but also because of object responsibility. using an ADM means that one can concentrate on modeling the domain objects for what they are. The job of object responsibility becomes easier in an ADM world because the domain objects only have to concentrate on being themselves and the responsibility of an object is not blurred. How often have we seen the RDM and asked "why on earth has bob put that method in that object"?
So, I like the ADM. When coupled with a decent framework on which to build our web based applications, I find it a tried and tested method that ensures the same maintainability, readability and de-coupled approach time and time again.
Cheers
Rich
A well documented bug in ASP.NET 2.0 (even more documented now) is getting loss of Intellisense when editing the web.config file. To get around this, simply remove the xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0" text.
Cheers
Rich
For some time now, we have experinced some strange random timeout problems on various web applications. We have a load balanced environment with up to 6 web servers sitting behind a rather nice load balancer.
In our web applications, session timout is set at the standard 20 minutes. It is also set at 20 minutes in IIS, so everything should work fine.
However, what we have been finding is that on, what looks like a random basis, the session has timed out. Sometimes it's 20 minutes, othertimes it's 5 minutes. The first thing that we looked at was the application pool behaviour to see if the application pool was re-cycling early and kicking the sessions.
It wasn't
However, when we tried to relpicate, we could never relicate it when we went directly to one of the web servers, and sometimes replicate it when we went via the load balancer.
The load balancer was therefore the problem. The load balancer used sticky concurrent sessions, so we shouldn't experience problems. However, sticky concurrency comes with a timeout of 5 minutes. This meant that the following would happen:
- User would come in via load balancer and be assigned to web server 1
- User would leave browser open and idle for over 5 minutes, but under 20 minutes
- The sticky concurrency would timeout
- If web server 1 were busy, the user would be pushed onto web server 2 loosing the inProc session on web server 1
So, if you are using InProc sessions in a load balanced environment with sticky concurrent sessions and experience random timeouts, there are a couple of things that could be changed.
- Stop using InProc sessions and use a state server or Sql server to hold sessions in one place
- Increase the sticky concurrent timeout to a value equal to or above the session timeout
Cheers
Rich
If, like me you use Nant to build many projects in one go, then after some time, the list of projects that need to be built can get quite large. All of the build scripts I run tend to build in release mode, though we build locally in debug mode.
I suggest looking through the build logs after adding a new project to make sure that it is actually being built. The other day, I added a new solution to the build and after looking in the logs found that most of the projects were being skipped. The solution was simple. Use the configuration section in the solution properties of Visual Studio to make sure that the mode that you are building in has the projects set to actually build the project. It sounds simple, but it could keep one guessing for a long time after a long week on a Friday afternoon!
Cheers
Rich
10 Must-Have free tools for the .NET developer
Well, there are a lot more than 10, but here are some of my favorite free tools
that I think every .NET developer should be using.
1: Nant
What is it?
Namt is a build tool. Build
scripts are written that can perform tasks
on your build server. Tasks are a-plenty, but typical tasks include the ability
to build .NET solutions, run unit tests, copy files, make and delete
directories and many more. In fact, with the ability to write custom takss for
Nanr, there are plenty of possibilities.
Where can I find it?
Nant can be found at:
http://nant.sourceforge.net/
2: CruiseControl.NET
What is it?
CruiseControl.NET is an Automated Continuous Integration server for .NET.
CruiseControl.NET will monitor your source control repository and run your
build scripts at set intervals, or whenever a file is checked in.
CruiseControl.NET also provides a dashboard web application to view logs and
status, plus a system tray application for all developers to install. This way,
everyone knows who broke the build!
Where can I find it?
CruiseControl.NET can be found at:
3: Nunit
What is it?
If you're not already unit testing your code, then you certiainly should be.
Nunit allows you to write unit tests in your .NET language against your code.
The GUI is easy to use and gives a developer confidence to make changes to
code. Nunit can be integrated into your build (Nant) so tests can be automated.
Where can I find it?
Nunit can be found at:
http://www.nunit.org/
4: TestDriven.NET
What is it?
TestDriven.NET is a free add-in for Visual Studio that piggy-backs on Nunit. It
adds quick access, right mouse click functionality to run your unit tests,
showing the results in the output window. You can even debug your tests from
the right mouse button.
Where can I find it?
TestDriven.NET can be found at:
http://www.testdriven.net/
5: RegEx Designer.NET
What is it?
If you've written validation for your .NET sites, regular expressions can be a
pain to get to grips with. The RegExDesigner allows you to test out your
regular expressions and even generate .NET code from your regular expressions.
Where can I find it?
RegExDesigner.NET can be found at:
http://www.sellsbrothers.com/tools/#regexd
6: FxCop
What is it?
FxCop is a code analysis tool that checks your code for standards conformance.
GUI and command line is available and again can be automatically run via your
build script.
Where can I find it?
FxCop can be found at:
http://www.gotdotnet.com/team/fxcop/
7: NDoc
What is it?
NDoc generates class library documentation from .NET assemblies and the XML
documentation files generated by the C# compiler Ndoc allows you to produce
HTML or MSDN Style documentation.. Using Ndoc is as simple as filling in your
.NET XML Comments.
Where can I find it?
Ndoc can be found at:
http://ndoc.sourceforge.net/
8: NunitASP
What is it?
Like Nunit, NunitASP is for unit testing.But in the case of NunitASP, this is
an Nunit extension that is used to test the code-behind pages o your ASP.NET
applications. You can program tests to click buttons, select an array of web
controls and other useful features.
9: The MONO Project
What is it?
Mono is not just free software. The mono project attempts to
make the .NET platform not only language interoperable, but platform
independent. The mono website reads: Mono provides the necessary software to
develop and run .NET client and server applications on Linux, Solaris,
Mac OS X, Windows, and Unix. Sponsored by
Novell, the Mono open source project has an active and enthusiastic
contributing community and is positioned to become the leading choice for
development of Linux applications.
Mono isn't for everyone, but if you are targeting (for example) a unix system
and wanting to stay with .NET. then this is the way to go.
10: NCover
What is it?
It's all very well unit testing your code, but how much of it
are you really testing? NCover highlights the areas of your code that are not
being tested.
I hope that this has helped to hightlight a few of the great
tools that are out there that are available for free. There are plenty others,
including servers, charting tools and O/R Mappers. Have a look at:
http://csharp-source.net/ for more.
Cheers
Rich
More strange behaviour from NANT today. A new project was started so I made the build script for the new projects that were to be included in the build. When trying to build, it would keep failing, telling me that it couldn't find a few of the references.
The really strange thing was, was that the references were in the correct place on the build server and were obviously there. (I found myself actually talking to the build server at one point, shouting "Can't you see that they are there!"
With verbose on, I could see that the build server was getting itself into a bit of a pickle and that it was looking for the missing assembly references in the administrator's Documents & Settings\Local etc... This was very odd, as other projects that were using the same assmblies and configured the same way were building fine.
The solution
In the end, the way to fix this was just as odd. I had to copy the so-called missing assemblies into the place that the build server thought they were. Once this was done, it would of course build ok. The really curious thing is that after it had built once correctly on the build server, I deleted the files (leaving the real ones stil in place) and all worked fine on concecutive builds.
Cheers
Rich
Embarking on a new project I decided that it would be a much better idea this time to separate the nunit test cases into separate projects from the production assemblies. I had read the recent article in VSJ magazine and was ready put into practice those things that I wasn't routinely doing (I.e. separating my test cases from my production class libraries.
So, the first thing that I wanted to do was write some quick scratch code in order to make sure that everything would work. My scratch code doesn't always tend to be quick as I want to make sure that it works under as many scenarios as possible. Firstly, I made a class library called CompanyName.ExampleProject.dll, wrote a class in the class library, and of course a couple of methods in the class to be able to test. Let's say then we had:
CompanyName.ExampleProject.MyClass that contained:
public string SayHello() method.
All fine so far. Then, being that I like to make sure that everything is set up in the normal fashion, i altered the AssemblyInfo file, adding in all the usual bits like AssemblyTitle, AssemblyCopyright and AssemblyCulture.
Great, I'm all set-up. Now to try and write another project to test it.
So, I set-up another project called CompanyName.TestExampleProject.dll. In a class in this library, I added an nunit test to test the CompanyName.ExampleProject.MyClass class. All looked fine, very little code to test. Run the test.
CompanyName.TestExampleProject.Tests.TestMyClass : System.IO.FileNotFoundException : File or assembly name CompanyName.ExampleProject, or one of its dependencies, was not found.
How odd. Everything compiled correctly and i could even instantiate the SayHello() method from a separate web project, so there was certainly nothing missing.
I verified that everything was in the proper place and that the code was as simple as possible. However, the only thing that I needed to do to make the test pass was to remove any reference to MyClass.
Even if I simply made a fake test and added a line: MyClass c1 = new MyClass then nunit would return the same error message.
Ok, so what would happen if I added the test into the same assembly as the MyClass class? Yep, just as in other projects, now everything would pass. So i could now make my test pass or fail,simply by moving it into another assembly. This shouldn't happen.
Looked at the more specific error message generated by nunit.
at System.Reflection.RuntimeConstructorInfo.InternalInvoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean isBinderDefault)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at NUnit.Core.Reflect.Construct(Type type) at NUnit.Core.TestFixture.DoSetUp(TestResult suiteResult)
After more testing, i found the answer. i had added an AssemblyCulture to the main project assembly. Yes, this is a good thing to do. The culture I had added was perfectly legal (en-GB). With the test in the test project (CompanyName.TestExampleProject.dll), if I changed the AssemblyCulture in the other assembly (CompanyName.ExampleProject.dll) to something illegal (E.g. hello) then nunit would tell me straight away that the culture info is not valid. That's good. However, if I changed it to a legal culture, then nunit would not complain until I tried to run the tests.
conclusion
It's my conclusion that this is a bug in nunit. In order to separate my nunit tests into a separate project I need to remove the AssemblyCulture information from the assembly that is being tested. Hardly ideal, but worth it to be able to separate the tests from the production code.
Cheers
R
Finally.I got round to automatically deploying our web projects to our development server today in our build script. I thought that it was all going to be very easy. After all, Nant has lots of tasks, ready made to choose from.
When I came o have a look at it, I found that the standard copy task would probably not be suitable. After all, I don't want every file moving over to the dev server from the build server. So the next thing was to look into writing a custom Nant task.
Can I copy project?
First, I thought that I would try and use the EnvDte and VSLangProj references to build a programmatic CopyProject feature, like the one that is built into Visual Studio. This turned out to be pretty easy to code as I have done this before but the problem was that didn't have a version of VS.NET on the build server, just the SDK, and the CopyProject feature needs to create an instance of Visual Studio from its progId. Goodbye to that idea.
Bespoke Copy
In the end, I threw together a class, based on the Nant.Core tasks that would simply copy all files and folders recursively from the source to the target. I am also able to supply a list of files that I don't want to carry over. Something like this:
< copyproject source="C:\Inetpub\wwwroot\MyWebFolder" target="\\MyDevServer\share$\website\MyWebFolder" >
< excludefiles >
< fileextension name="VS Project Files" value=".csproj" />
< fileextension name="VSS Files" value=".vss" />
< excludefiles />
< copyproject />
This is great, but I'll be looking for a way to improve this. I had a bit of a look over the other Nant contrib tasks but couldn't immediately see anything that would be of use. Still, this only took a couple of hours to do and it all works pretty well. Build time is still small for a solution containing 22 projects with a complete deployment of 6 web projects to 2 web servers.
Cheers
R
Strange. The problem is now fixed. To recap, I was basically getting loss of event handlers on an ASP.NET page when I was accessing the page via a link on another page in a seperate virtual directory. Link to the problem is:
http://www.dotnetjunkies.com/WebLog/richardslade/archive/2005/08/24/132134.aspx. As this was our development server, I was able to look at the IIS Configuration. On the properties of the Project 2 virtual directory, this was using anonymous access.
Integrated Windows Authentication was off. Checking this option made all the event handlers work. Turning it off again seemed to disable any button events. This could be consistantly replicated.
Have a bit of a problem. I'm sure that I will get it solved, but it is proving to be rather tricky. Perhaps there is something obvious that I have missed. After all, my bleary eyes were tired and crumpled from the days coding. Here is what is happening, what we have in place and how I replicate my strange situation.
We have 2 development web servers, load balanced with sticky concurrent sessions.
We have many web projects in one solution, but in this example problem I only need 2 projects.
Each project is published to both web servers
The web servers are both set up in the same way
Each of the two projects sits under a separate virtual directory (E.g.
www.mysite.com/Project1 and
www.mysite.com/Project1/Project2)
Project 1 uses NT Authentication and so does not allow anonymous access
Project 2 allows anonymous access
The problem
From www.mysite.com/Project1 there are a set of links. One of these links takes the users to www.mysite.com/Project1/Project2 . On the project 2 section, there are some buttons with normal .net event handlers behind them. If I navigate directly to www.mysite.com/Project1/Project2 then all works fine. However, if I navigate to www.mysite.com/Project1 , click on the link to project 2, then all of the buttons on project 2 have lost the event handlers. The buttons do nothing more than reload the page. Even more strangely, after I see that project 2 is not working, if I copy the url, close the browser and re-open it, pasting in the url that was not working (project2) then all works fine.
So, in the morning, I guess I'm just going to run a whole series of tests, and will hopefully be able to post how this was solved, and probably the silly thing that I haven't yet thought of. However, if someone else has ever seen anything like this, please feel free to share the love and let me know what on earth it could be. Solution to follow (one hopes)....
Hmm, I see that there is often debate about what should and shouldn't be tested with regard to unit tests.Many beleive that it is enough to test all the public methods of a system while others are sure that every method should be fully unit tested. This, for me at least is a tough one. There are, I think many factors to consider.
So, what are the factors involved? - Here are just three.
Pressure from the business to write production ready code. Yesterday
The difficulty in testing private methods
Public methods are exposed interfaces, therefore if these are fully tested, why test what they call.
It doesn't quite sit right with me that each part of the system isn't tested. After all, there is no more reason why the private methods shouldn't break than the public ones. Why should private methods suffer the loneliness of a test-free life. On the other hand, these are hidden chaps that are never exposed to our clients. All those proud public method chaps are sitting on the front line and happily calling the privates for help when needed.
Also, to test the private methods seems like it's going to add some overhead, certainly in time and resource. If our public methods are properly, no really properly tested then we would also be duplicating some of the testing, surely.
In my experience, there is always a balance to strike between doing the best possible to ensure that we write robust, maintainable and bug free software and resigning ourselves to the fact that it's the busness that pay our wages and if we can test what we expose well enough then we are saving ourselves time and overhead while still delivering on-time and within budget.
By now you should know which side ofthe fence I sit on. Test all your public interfaces, but do it well.
For those interested, here is a link to a good a