How to use Rhino Mocks - documented through tests

Posted on March 12th, 2010 in .NET, Rhino Mocks, TDD, unit testing by Jon Kruger

I wanted to come up with a way to show people how to use Rhino Mocks (other than telling them to read the documentation). What better way to do this than by showing you how it works through a bunch of simple unit tests that document how Rhino Mocks works?

So that’s what I did. You can view the code here, or if you want to download the whole project and run the tests, you can get the whole thing here.

(If you’re interested in Moq, how it compares to Rhino Mocks, and to see Moq documented through tests, check out Steve Horn’s post.)

UPDATE: Fixed the test that was incorrectly showing how to use Expect() and VerifyAllExpectations(). Thanks to Sharon for pointing this out.


Kick It on DotNetKicks.com

Hiding Thread.CurrentPrincipal from your code

Posted on April 13th, 2009 in .NET, ASP.NET MVC, unit testing by Jon Kruger

You can get information about the current user who is logged in using Thread.CurrentPrincipal. The problem with this is that it’s difficult to work with it in tests. It forces you to set the current principal in your test setup so that your code will work correctly, and this can be difficult if not impossible in situations where you’re using Windows Authentication (if you’re using Forms Authentication, it’s not quite as painful, but it’s still a pain).

I don’t like to actually have calls to Thread.CurrentPrincipal scattered throughout my code. It makes my code less readable. Usually if I’m checking the principal, I want to know what user is logged in. That leads to code like this:

var currentUser = null;
var principal = Thread.CurrentPrincipal as MyCustomPrincipal;
if (principal != null)
    currentUser = ((MyCustomPrincipal) Thread.CurrentPrincipal).User;

Ick. I don’t want to write this over and over throughout my code. What if I had a class called PrincipalFactory that dealt with everything having to do with the principal? My class could look like this:

public class PrincipalFactory : IPrincipalFactory
{
    public MyCustomPrincipal GetCurrent()
    {
        return Thread.CurrentPrincipal as MyCustomPrincipal;
    }
 
    public User GetCurrentUser()
    {
        var principal = GetCurrent();
        return (principal != null ? principal.User : null);
    }
 
    public void SetCurrentUser(User user)
    {
        Thread.CurrentPrincipal = new MyCustomPrincipal(user);
    }
}

Now when I want to know who the current user is, I can write…

var currentUser = _principalFactory.GetCurrentUser();

Isn’t that much easier on the eyes?

It’s much easier to test too. I always use dependency injection and StructureMap, which also makes testing easier. Let’s say I had a class like this:

public class AccountController : Controller
{
    private IPrincipalFactory _principalFactory;
 
    public AccountController(IPrincipalFactory principalFactory)
    {
        _principalFactory = principalFactory;
    }
 
    [Authorize]
    public ActionResult Index()
    {
        var model = new IndexViewModel();
        model.WelcomeMessage = "Hello, " + _principalFactory.GetCurrentUser().Username;
        return View(model);
    }
}

In my test code, I’m going to use Rhino Mocks to stub out the IPrincipalFactory. So the test will essentially pretend that a user named “Jon” is the current user and then we’ll make sure that the Index() method does the right thing.

using System;
using NUnit.Framework;
using Rhino.Mocks;
 
[TestFixture]
public class When_displaying_the_index_view()
{
    [Test]
    public void Should_display_the_welcome_message_for_the_current_user()
    {
        // Arrange
        var principalFactory = MockRepository.GenerateStub<IPrincipalFactory>();
        principalFactory.Stub(pf => pf.GetCurrentUser()).Return(new User { Username = "Jon" });
 
        var controller = new AccountController(principalFactory);
 
        // Act
        controller.Index();
 
        // Assert
        Assert.IsTrue(((IndexViewModel)_controller.ViewData.Model).WelcomeMessage, Is.EqualTo("Welcome, Jon"));
    }
}

This is much easier and cleaner than having to deal with Thread.CurrentPrincipal all over the place. If you didn’t hide Thread.CurrentPrincipal inside the PrincipalFactory class, you could still test it by setting Thread.CurrentPrincipal in the beginning of your test. I’ve been on projects that did it this way, and inevitably someone forgets to set Thread.CurrentPrincipal back to what it was before the test, or an exception happens and somehow the code that sets it back to the original value doesn’t run, and now tests will have different outcomes depending on what order you run them and which ones you run. This is usually a real pain to debug because you don’t know which test is causing the problem. Not fun.


Kick It on DotNetKicks.com

Helping everyday developers succeed

Posted on January 22nd, 2009 in .NET, Design, Fluent NHibernate, LINQ, NHibernate, WCF by Jon Kruger

Software development is hard. You have to know how to use so many different tools and you have to try and keep up with it all.

Lately I’ve been hearing some griping about certain tools that people feel are trading good software design principles for ease of use. Many of these tools usually have some kind of drag-and-drop designer functionality that is designed to help you get things done faster. The griping comes from the fact that these tools can cause developers to make poor design decisions because the drag-and-drop tool led them in the wrong direction. I can’t say that I disagree with these complaints.

There are two sides of every coin, so let’s swing the pendulum the other way. Many open source libraries that I’ve seen take a different approach to design and the people that write them say that they’re not writing them for the novice user and that you will have to be familiar with advanced design patterns in order to use these tools. I think this is a good thing because software development is complicated and it’s OK to have make a library more complicated so that it fits in with good design patterns (like the need for an IoC container in FubuMVC).

Sometimes I wonder if we could do more to make these complicated tools easier to use. Take ORMs for example. Most people out there would agree that NHibernate is the most fully-functional ORM that we have. Yet I was on a project a couple years ago where developers floundered around trying to get their NHibernate mapping files to work (usually because of stupid stuff like typos, not making the .hbm.xml files Embedded Resources, not fully qualifying an assembly name, not making something virtual, etc.). Eventually we got better at it and we learned the tricks, but we wasted a ton of time trying to fix stupid mapping file issues.

For the next project I was on, we chose LINQ to SQL over NHibernate (this was in early 2008 when LINQ to SQL had just come out). I had an existing database with my tables in it, so I dragged them all into the LINQ to SQL designer and started writing business logic. It was amazing! It all just worked!

Now that led me into other pitfalls because now I had to map my objects 1:1 with my database tables, and crap from the database concerns cluttered up my model and caused a lot of grief. But even with that, we got work done much faster with LINQ to SQL than with NHibernate. Does this mean that LINQ to SQL is “better” than NHibernate? I wouldn’t say that, yet I was able to be more successful with LINQ to SQL. This is an important thing to note.

Open source tools like NHibernate are usually written by really smart people. Really smart people have no trouble figuring out complicated stuff. Sure, they may experience the same pain at first, but they pick it up quickly. All of the other really smart people that they talk to understand it too.

Not everyone is really really smart, unfortunately. I hear a lot of people harp on NHibernate and say it’s way too hard to use, that it’s not worth it, that there has to be a better way, etc. Most of these opinions come from a bad experience that they had with NHibernate.

I can’t discount these opinions that people may have. While these same people may agree that NHibernate is the most fully-featured ORM out there, for them it is not the ORM that will make them the most successful. I know a lot of people in this camp and they are not stupid people and they aren’t too lazy to learn NHibernate. It’s just that NHibernate did not lead them into the pit of success.

The fact is that most developers that are going to be using tools like NHibernate are your common, average, everyday developer — not bad developers by any stretch of the imagination, but they’re not as smart as the really smart people. I’m certainly not saying that we should sacrifice functionality and good design patterns to make things easier to use. I just think that more effort should be spent on making sure that average developers can figure out how to use something correctly, whether through documentation, good examples, or coming up with easier ways to do things. Really smart people don’t need these things to be successful with these tools, but the average developer will benefit immensely.

For me, this is what Fluent NHibernate did for NHibernate - it abstracted away a lot of what was difficult about NHibernate. Recently I’ve been able to use it on a project and it totally turned the tables. Now I get the power of NHibernate but I can use conventions to auto-wire my mappings, and the mappings are all in code instead of in XML. For me this is a huge deal. Now I get the power of NHibernate and I’m not stuck doing all of the crap that slowed me down before.

Another example of this is the reams and reams of documentation that the Microsoft patterns & practices team has written up for writing secure applications with WCF. WCF is very complex and powerful, but Microsoft did not leave us hanging and wrote up what to do in almost every scenario imaginable. They didn’t just give us a tool, they gave us what we needed to be successful with it.

We need more stuff like this.


Kick It on DotNetKicks.com

Best WCF Blog Ever

Posted on June 7th, 2008 in .NET by Jon Kruger

I’ve used WCF on the last few projects that I’ve worked on. While WCF is pretty cool, it’s not easy, and knowing how to configure it can be tough since you can customize anything and everything.

If you are doing anything at all with WCF, J.D. Meier’s blog is a definite must read. He (and his team) have been posting tons of WCF guidance articles on how to configure WCF in lots of different situations. These articles have been invaluable for me and now I actually feel confident that I’m doing everything correctly with WCF.


Kick It on DotNetKicks.com

LINQ to SQL talk stuff

Posted on February 29th, 2008 in .NET, LINQ by Jon Kruger

Here is the sample project from my talk at the Columbus .NET Users’ Group last night. If you open the project, you’ll notice a Northwind.sql file. This is my modified version of the Northwind database (I had to add a timestamp column to the Employees table to get it to cooperate with LINQ to SQL).

Like I mentioned yesterday, if you’re new to LINQ to SQL, a great place to start is Scott Guthrie’s series of blog posts on LINQ to SQL. Here they are:

Part 1: Introduction to LINQ to SQL
Part 2: Defining our Data Model Classes
Part 3: Querying our Database
Part 4: Updating our Database
Part 5: Binding UI using the ASP:LinqDataSource Control
Part 6: Retrieving Data Using Stored Procedures
Part 7: Updating our Database using Stored Procedures
Part 8: Executing Custom SQL Expressions
Part 9: Using a Custom LINQ Expression with the <asp:LinqDatasource> control


Kick It on DotNetKicks.com

LINQ to SQL In Disconnected/N-Tier scenarios: Saving an Object

Posted on February 10th, 2008 in .NET, LINQ by Jon Kruger

LINQ to SQL is a great tool, but when you’re using it in an n-tier scenario, there are several problems that you have to solve. A simple example is a web service that allows you to retrieve a record of data and save a record of data when the object that you are loading/saving had child lists of objects. Here are some of the problems that you have to solve:

1) How can you create these web services without having to create a separate set of entity objects (that is, we want to use the entity objects that the LINQ to SQL designer generates for us)?
2) What do we have to do to get LINQ to SQL to work with entities passed in through web services?
3) How do you create these loading/saving web services while keeping the amount of data passed across the wire to a minimum?

I created a sample project using the Northwind sample database. The first thing to do is to create your .dbml file and then drag tables from the Server Explorer onto the design surface. I have something that looks like this:

dbml

I’m also going to click on blank space in the design surface, go to the Properties window, and set the SerializationMode to Unidirectional. This will put the [DataContract] and [DataMember] attributes on the designer-generated entity objects so that they can be used in WCF services.

SerializationMode

Now I’ll create some web services that look something like this:

public class EmployeeService
{
  public Employee GetEmployee(int employeeId)
  {
    NorthwindDataContext dc = new NorthwindDataContext();
    Employee employee = dc.Employees.FirstOrDefault(e => e.EmployeeID == employeeId);
    return employee;
  }
 
  public void SaveEmployee(Employee employee)
  {
    // TODO
  }
}

I have two web service methods — one that loads an Employee by ID and one that saves an Employee.

Notice that both web service methods are using the entity objects generated by LINQ to SQL. There are some situations when you will not want to use the LINQ to SQL generated entities. For example, if you’re exposing a public web service, you probably don’t want to use the LINQ to SQL entities because that can make it a lot harder for you to refactor your database or your object model without having to change the web service definition, which could break code that calls the web service. In my case, I have a web service where I own both sides of the wire and this service is not exposed publicly, so I don’t have these concerns.

The GetEmployee() method is fairly straight-forward — just load up the object and return it. Let’s look at how we should implement SaveEmployee().

In order for the DataContext to be able to save an object that wasn’t loaded from the same DataContext, you have to let the DataContext know about the object. How you do this depends on whether the object has ever been saved before.

How you make this determination is based on your own convention. Since I’m dealing with integer primary keys with identity insert starting at 1, I can assume that if the primary key value is < 1, this object is new.

Let's create a base class for our entity object called BusinessEntityBase and have that class expose a property called IsNew. This property will return a boolean value based on the primary key value of this object.

namespace Northwind
{
  [DataContract]
  public abstract class BusinessEntityBase
  {
    public abstract int Id { get; set; }
 
    public virtual bool IsNew
    {
      get { return this.Id <= 0; }
    }
  }
}

Now we have to tell Employee to derive from BusinessEntityBase. We can do this because the entities that LINQ to SQL generates are partial classes that don’t derive from any class, so we can define that in our half of the partial class.

namespace Northwind
{
  public partial class Employee : BusinessEntityBase
  {
    public override int Id
    {
      get { return this.EmployeeID; }
      set { this.EmployeeID = value; }
    }
  }
}

Now we should be able to tell if an Employee object is new or not. I’m also going to do the same thing with the Order class since the Employee object contains a list of Order objects.

namespace Northwind
{
  public partial class Order : BusinessEntityBase
  {
    public override int Id
    {
      get { return this.OrderID; }
      set { this.OrderID = value; }
    }
  }
}

OK, let’s start filling out the SaveEmployee() method.

public void SaveEmployee(Employee employee)
{
  NorthwindDataContext dc = new NorthwindDataContext();
  if (employee.IsNew)
    dc.Employees.InsertOnSubmit(employee);
  else
    dc.Employees.Attach(employee);
  dc.SubmitChanges();
}

Great. So now I can call the GetEmployee() web method to get an employee, change something on the Employee object, and call the SaveEmployee() web method to save it. But when I do it, nothing happens.

The problem is with this line:

public void SaveEmployee(Employee employee)
{
  NorthwindDataContext dc = new NorthwindDataContext();
  if (employee.IsNew)
    dc.Employees.InsertOnSubmit(employee);
  else
    dc.Employees.Attach(employee); // <-- PROBLEM HERE
  dc.SubmitChanges();
}

The Attach() method attaches the entity object to the DataContext so that the DataContext can save it. But the overload that I called just attached the entity to the DataContext and didn’t check to see that anything on the object had been changed. That doesn’t do us a whole lot of good. Let’s try this overload:

public void SaveEmployee(Employee employee)
{
  NorthwindDataContext dc = new NorthwindDataContext();
  if (employee.IsNew)
    dc.Employees.InsertOnSubmit(employee);
  else
    dc.Employees.Attach(employee, true); // <-- UPDATE
  dc.SubmitChanges();
}

This second parameter is going to tell LINQ to SQL that it should treat this entity as modified so that it needs to be saved to the database. Now when I call SaveEmployee(), I get an exception when I call Attach() that says:

An entity can only be attached as modified without original state if it declares a version member or does not have an update check policy.

What this means is that my database table does not have a timestamp column on it. Without a timestamp, LINQ to SQL can’t do it’s optimistic concurrency checking. No big deal, I’ll go add timestamp columns to the Employees and Orders tables in the database. I’ll also have to go into my DBML file and add the column to the table in there. You can either add a new property to the object by right-clicking on the object in the designer and selecting Add / Property, or you can just delete the object from the designer and then dragging it back on from the Server Explorer.

Now the DBML looks like this:

updated dbml

Now let’s try calling SaveEmployee() again. This time it works. Here is the SQL that LINQ to SQL ran:


UPDATE [dbo].[Employees]
SET [LastName] = @p2, [FirstName] = @p3, [Title] = @p4, [TitleOfCourtesy] = @p5, [BirthDate] = @p6, [HireDate] = @p7, [Address] = @p8, [City] = @p9, [Region] = @p10, [PostalCode] = @p11, [Country] = @p12, [HomePhone] = @p13, [Extension] = @p14, [Photo] = @p15, [Notes] = @p16, [ReportsTo] = @p17, [PhotoPath] = @p18
WHERE ([EmployeeID] = @p0) AND ([Timestamp] = @p1)
 
SELECT [t1].[Timestamp]
FROM [dbo].[Employees] AS [t1]
WHERE ((@@ROWCOUNT) > 0) AND ([t1].[EmployeeID] = @p19)
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [5]
-- @p1: Input Timestamp (Size = 8; Prec = 0; Scale = 0) [SqlBinary(8)]
-- @p2: Input NVarChar (Size = 8; Prec = 0; Scale = 0) [Buchanan]
-- @p3: Input NVarChar (Size = 6; Prec = 0; Scale = 0) [Steven]
-- @p4: Input NVarChar (Size = 13; Prec = 0; Scale = 0) [Sales Manager]
-- @p5: Input NVarChar (Size = 3; Prec = 0; Scale = 0) [Mr.]
-- @p6: Input DateTime (Size = 0; Prec = 0; Scale = 0) [3/4/1955 12:00:00 AM]
-- @p7: Input DateTime (Size = 0; Prec = 0; Scale = 0) [10/17/1993 12:00:00 AM]
-- @p8: Input NVarChar (Size = 15; Prec = 0; Scale = 0) [14 Garrett Hill]
-- @p9: Input NVarChar (Size = 6; Prec = 0; Scale = 0) [London]
-- @p10: Input NVarChar (Size = 0; Prec = 0; Scale = 0) [Null]
-- @p11: Input NVarChar (Size = 7; Prec = 0; Scale = 0) [SW2 8JR]
-- @p12: Input NVarChar (Size = 2; Prec = 0; Scale = 0) [UK]
-- @p13: Input NVarChar (Size = 13; Prec = 0; Scale = 0) [(71) 555-4848]
-- @p14: Input NVarChar (Size = 4; Prec = 0; Scale = 0) [3453]
-- @p15: Input Image (Size = 21626; Prec = 0; Scale = 0) [SqlBinary(21626)]
-- @p16: Input NText (Size = 448; Prec = 0; Scale = 0) [Steven Buchanan graduated from St. Andrews University, Scotland, with a BSC degree in 1976.  Upon joining the company as a sales representative in 1992, he spent 6 months in an orientation program at the Seattle office and then returned to his permanent post in London.  He was promoted to sales manager in March 1993.  Mr. Buchanan has completed the courses "Successful Telemarketing" and "International Sales Management."  He is fluent in French.]
-- @p17: Input Int (Size = 0; Prec = 0; Scale = 0) [2]
-- @p18: Input NVarChar (Size = 37; Prec = 0; Scale = 0) [http://accweb/emmployees/buchanan.bmp]
-- @p19: Input Int (Size = 0; Prec = 0; Scale = 0) [5]

Notice that it passed back all of the properties in the SQL statement — not just the one that I changed (I only changed one property when I made this call). But isn’t it horribly ineffecient to save every property when only one property changed?

Well, you don’t have much choice here. Now there is another overload of Attach() that takes in the original version of the object instead of the boolean parameter. In other words, it is saying that it will compare your object with the original version of the object and see if any properties are different, and then only update those properties in the SQL statement.

Unfortunately, there’s no good way to use this overload in this case, nor do I think you would want to. I suppose you could load up the existing version of the entity from the database and then pass that into Attach() as the “original”, but now we’re doing even more work — we’re doing a SELECT that selects the entire row, and then we’re doing an UPDATE that only updates the changed properties. I would rather stick with the one UPDATE that updates everything.


Kick It on DotNetKicks.com

LINQ to SQL: a three-month checkpoint

Posted on January 19th, 2008 in .NET, LINQ by Jon Kruger

We are now about 3 months into our project using LINQ to SQL. Our project is a Winforms app using SQL Server 2005 (LINQ to SQL only works with SQL Server). We are planning on moving to an n-tier system with a WCF service layer, but for now our application talks directly to the database. Even though we don’t have the service layer in there yet, we’re architecting the system as if we had the service layer in there so we’re having many of the same issues that we will have when actually have the service layer.

Microsoft hasn’t always been known for stellar 1.0 releases (e.g. Vista, the Zune, etc.). When it comes to something that’s in the .NET Framework, I had a little more faith because it’s a little harder for them to go back and fix something if they screw it up. I figured that because of that, they’ll make sure that they get it right.

LINQ to SQL is not complete. There are some issues that Microsoft knows about that LINQ to SQL doesn’t currently handle. None of these issues are show-stoppers. While we’ve had to jump through some hoops to get around these issues, but we’ve been able to do everything that we’ve needed to do. I’ll get into more detail on the hoop-jumping in later posts.

Even with all of these issues, I give LINQ to SQL a rousing endorsement. I’ve always been an ORM fan, and I’ve used Nhibernate on several projects.

Getting Started

When we started our project, we inherited a legacy database that has been developed over the last 10 years. There are some interesting things in the database, such as numerics being used as primary keys, tables that aren’t normalized, and spotty referential integrity.

For the first week, three of us dragged all of the tables onto the LINQ to SQL designer and renamed all the properties to more friendly names. This was a fairly painless process. Now we had all of our entity objects created and ready to go.

Well, almost. We created a BusinessEntityBase class and all of the entity objects derive from this class. We do this by creating partial classes that match up with the classes generated by LINQ to SQL (all of the classes generated by LINQ to SQL are partial classes) and specifying that those classes derive from BusinessEntityBase. We don’t have much in the BusinessEntityBase class — the main thing in there is an abstract Id property that each entity must override to specify the value of the primary key. We use this to keep track of whether an entity object is unsaved or not.

At this point, we were ready to start working! All of our entity objects were generated for us. Contrast this with Nhibernate, where we had to write (or generate) all of our entity objects and the Nhibernate mapping files. It takes most people a long time to figure out how to write those Nhibernate mapping files!

Working with LINQ

“LINQ” is the general term for the syntax that we now use to write queries. These queries can be executed against a database (LINQ to SQL), a collection (LINQ to Objects), and various other things (LINQ to Amazon).

The LINQ syntax and particularly lambda expressions were very foreign concepts at first. You’re just not used to using those types of things in C# code. Then one day is just clicks, and you start discovering all kinds of new ways to use LINQ queries and lambda expressions.

Personally, I think lambda expressions are more revolutionary than the LINQ syntax. They don’t provide you with anything that you couldn’t do in .NET 2.0 with anonymous delegates, but now the syntax is much more concise. You can do what you want to do in fewer lines of code, which also makes for more readable code. Here’s an example of why I like lambda expressions.

Let’s say that I’m working with everyone’s favorite sample database (Northwind) and I want to find a Employee by first name, last name, or both. In the past, you probably wrote a stored procedure that looked like this:

create procedure EmployeeSearch
     @FirstName varchar(20),
     @LastName varchar(20)
as
select EmployeeID, FirstName, LastName, Title, TitleOfCourtesy,
    BirthDate, HireDate, Address, City, Region, PostalCode, Country,
    HomePhone, Extension, Photo, Notes, ReportsTo, PhotoPath
from Employees
where (@FirstName is null or FirstName = @FirstName)
and (@LastName is null or LastName = @LastName)

That worked fine, but having to check if the parameters are null is a performance hit in the stored procedure, and someone had to write the stored procedure in the first place.

With lambda expressions and LINQ to SQL, you can now do something like this and build your query incrementally:

public IQueryable<Employee> SearchEmployees(string firstName, string lastName)
{
    NorthwindDataContext dc = new NorthwindDataContext();
 
    // We'll start with the entire list of employees.
    IQueryable<Employee> employees = dc.Employees;
 
    if (!string.IsNullOrEmpty(firstName))
    {
        // Filter the employees by first name
        employees = employees.Where(e => e.FirstName == firstName);
    }
 
    if (!string.IsNullOrEmpty(lastName))
    {
        // Filter the employees by last name
        employees = employees.Where(e => e.LastName == lastName);
    }
 
    return employees;
}

Why is this better?

  • We didn’t have to write a separate stored procedure.
  • The generated SQL code won’t have to check for NULL parameters passed into a stored procedure.
  • This code is much more testable and easier to read than a stored procedure (IMO).
  • This is compiled, type safe code!

Here is the SQL code that LINQ to SQL runs as a result of this method:

SELECT [t0].[EmployeeID], [t0].[LastName], [t0].[FirstName], [t0].[Title], [t0].[TitleOfCourtesy], [t0].[BirthDate], [t0].[HireDate], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[HomePhone], [t0].[Extension], [t0].[Photo], [t0].[Notes], [t0].[ReportsTo], [t0].[PhotoPath]
FROM [dbo].[Employees] AS [t0]
WHERE [t0].[LastName] = @p0
-- @p0: Input NVarChar (Size = 6; Prec = 0; Scale = 0) [Kruger]

I’m not saying that stored procedures are obsolete. There will still be cases where you have a query that is so complex that it’s easier to do it in a stored procedure, or it may not be possible to do it in LINQ at all. But LINQ to SQL is allowing me to scrap many of the stored procedures that I used in the past.

More to come…

Over the next few weeks, I’ll post in more detail about how we are using LINQ to SQL and some of the things we’ve had to do to make it work.


Kick It on DotNetKicks.com

Singing the praises of continuous integration

Posted on December 20th, 2007 in .NET by Jon Kruger

One thing that almost every project seems to struggle with is unit testing. Not so much the writing of said tests as much as the fact that inevitably you will get really busy and no one will run all of the unit tests for a week or so, and then all of a sudden you decide to run them and you find out that half of them are failing.

Many times these are easy to fix, but when there are so many failing, you don’t have time to dive in and fix them all. So no one fixes them, and the unit tests become pretty much worthless because you can’t count on any of them.

At this point, many people stop writing unit tests because they’re not used to ever running unit tests anymore, so they forget about writing them altogether.

Someone will eventually decide that the unit tests need to be fixed, so someone will spend an entire week fixing them all up. But by then the code coverage is lacking because people had stopped writing them (see above). You don’t have time to add tests at that point because you’re a week behind because you spent a week fixing unit tests.

For the first time I am working on a project where none of this is happening. Much of the credit goes to my co-workers, who do a great job of writing lots of good tests and keeping them up. But what is going to keep everything going is using continuous integration with TFS 2008.

I know, some people are getting ready to click the comment button and say that they’ve been doing CI with CruiseControl for years. CruiseControl is great, I won’t deny that.

Much to my surprise, it took me no more than 10 minutes to set up our CI build using TFS 2008. Now I can look at a dashboard screen and see that all 684 of our unit tests have been passing all day. If a check-in causes a test to break, everyone gets an email saying so and TFS automatically creates a bug for the person that broke it. So we stop and fix the tests right away and we get back to work.

Next up is to figure out how can configure our USB Missile Launcher to automatically shoot someone when they break the tests!


Kick It on DotNetKicks.com

Creating a custom handler for the Policy Injection Application Block

Posted on November 4th, 2007 in .NET by Jon Kruger

I’ve thought for awhile that the Policy Injection Application Block looked interesting, but now I’ve finally had a chance to use it. The basic idea is that you can wrap a method call with a “handler” which will execute custom code before and after the actual method is executed. The block comes with a bunch of handlers out of the box, but you can also add custom handlers that you can use either by putting a custom attribute on a method or by adding to the configuration file. This post explains in more detail how to use the Policy Injection Application Block.

I’ve taken the Policy Injection Quick Start solution and added a custom handler as an example. Here’s a quick overview of what I did:

  • Added four files:
    • MyHandler.cs - this is the file where you will write the custom code that you want to execute before and after the actual method call.
    • MyHandlerAssembler.cs - creates a MyHandler object from a configuration object.
    • MyHandlerAttribute.cs - attribute that creates a MyHandler object when placed on a class, method, or property.
    • MyHandlerData.cs - stores data from custom attributes when handlers are created in the configuration file.
  • There are two ways to add a handler, and either way will accomplish the same purpose.
    • Place a [MyHandler] attribute on a method, property, or class. In the BankAccount.cs class, I decorated the Deposit() method with a [MyHandler] attribute. If you run the application, click the Deposit button, enter a value, and click OK, code in MyHandler.Invoke() will be executed and you’ll see some stuff in the output window.
    • Add to the <policyInjection> section of the app.config file. If you open the app.config file and search for “My Custom Stuff” you will find the section that I have added. If you run the app and click the “Balance Inquiry” button, code in MyHandler.Invoke() will be executed and you’ll see some stuff in the output window.

Here is the quick start project with my changes included.

Hope this helps!


Kick It on DotNetKicks.com

How to step into NHibernate code

Posted on June 29th, 2007 in .NET, NHibernate by Jon Kruger

In 10 minutes you can be stepping into NHibernate code to see exactly what’s it’s doing with your project. Here’s how to do it:

1) Go download the NHibernate source code from here. As I’m writing this, the latest release version is 1.2.0.GA. (I’m assuming here that you already have NHibernate set up to work with your application.)
2) Unzip the source to a location on your machine.
3) Open the NHibernate.sln file in Visual Studio that corresponds to the version of the .NET framework that you are using (1.1 or 2.0). If you really want to build everything, including the Iesi.Collections assemblies and all the unit tests, then open the NHibernate-Everything.sln file, but for me this is overkill because I usually only want to step into the NHibernate code. If you build NHibernate-Everything.sln, you’ll have to have NUnit 2.2.8 installed to build the unit test projects.
4) Make sure the Debug configuration is selected and build the entire solution.
5) If you open the \src\NHibernate\bin\Debug-2.0 (or Debug-1.1) folder, you will see all of the assemblies along with the .pdb files (if you just build the NHibernate-1.1/-2.0.sln file, you will only see one .pdb — NHibernate.pdb). Copy all of the .dll and .pdb files to the location where you currently have your NHibernate .dll files in your project.

Now when you debug your project, you should be able to step into NHibernate code!

Obvious caveat: we’re assuming that the source code that you downloaded is the exact same code that they used to build the release assemblies. I don’t see any reason why this wouldn’t be the case, but I’ve run into this problem before with other third party packages (like Infragistics NetAdvantage controls). So it might not be a bad idea to remove the debug NHibernate dlls when you’re done stepping into them and put the release dlls back in so that you don’t get burned.

Hope this helps! If you encounter any problems with this process, please let me know.


Kick It on DotNetKicks.com
Next Page »