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.

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

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.

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.

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!

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!

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.

My First WPF App

Posted on June 19th, 2007 in .NET, WPF by Jon Kruger

12 hours in the car coming back from the Outer Banks means that I finally had time to delve into WPF. It seems like every other week Microsoft is telling us about some new technology that is coming out. I figured that rather than try and learn them all at once, I’ll concentrate on just one. I picked WPF because WPF will be used extensively in Silverlight and because all of the WPF apps I’ve seen so far look awesome.

WPF is a big change from any desktop application platform in the past in that it encourages you to design a rich user experience. WinForms apps almost always have the same look and feel — buttons look the same in every app, everyone uses the same menus, the same toolbars, etc., and it’s really difficult to change the look and feel of them. Now Microsoft is pushing you to use your imagination and creativity to do whatever you want, while giving you the tools you need to do so.

This is both exciting and challenging. It’s really hard to try and put aside all of the UI concepts, layouts, colors, etc. and try and think outside the box. With WPF, you can do stuff that you would’ve never dreamed of attemping in Windows Forms, and it’s not that hard to do. Coming up with the ideas is the hard part!

Here’s what you need to get started:

These installs all take a long time, so allow plenty of time. :)

Here’s where I learned everything that I know:

  • Reading Windows Presentation Foundation Unleashed, by Adam Nathan. I’m only about halfway through, but this book does an excellent job of walking you through everything. Normally I don’t buy dead tree books, but when you are learning something completely new, it’s nice to have someone walk you through everything in the correct order.
  • Downloaded the Family.Show app. This app was written in WPF as an example application that contained examples of everything that you might want to do in a WPF app.
  • Watched the Family.Show guys talk about their app in this video.
  • Watched this video on designing rich client experiences with Expression Blend and WPF.

For my application I chose to solve a problem that I have — I can’t keep track of car repairs and when they need to be done. So I’m going to create a simple application that will allow me to record car repairs that I do and let me know when I’m due to have the repairs done again.

Most WPF apps that you’ve seen out there do lots crazy animation and 3D rotating of panels. I tried to stay away from that for now and just do the basic stuff that I would do in a normal application. In WPF, the basic stuff actually is in some cases a lot harder than the animation and 3D rotations.

Some thoughts so far:

  • I did more work in Expression Blend than I did in Visual Studio. Anyone doing WPF will almost always use Blend and Visual Studio side by side. You can even compile and run in Blend.
  • Blend is a really powerful tool and it allows you do to all the styling, layout, and animation. Timelines and event handling make it easy to make your controls react to button clicks, hovering over something with the mouse, etc. The use of data binding is really encouraged in WPF, more than it was in Windows Forms, and Blend makes it easy to use data binding in all kinds of places.
  • The learning curve of Blend wasn’t as bad as I expected it to be. Watching the MIX videos that I mentioned earlier really helped me learn all of the basic stuff. When you do get stuck and can’t find something in Blend, you can go edit the XAML directly and then go back into Blend and see what changed.
  • The Visual Studio Extensions are supposed to install the “Cider” designer (which is still in CTP). I couldn’t get anything to show up at all in the designer. I don’t know if this was a problem with my environment or a bug, but it doesn’t really matter because there’s no reason to do anything in the VS designer when you have Blend.
  • There is also Expression Design, which is essentially MS’s version of Adobe Illustrator. I haven’t really used either, but the nice thing about Design is that it also outputs XAML, so you can bring stuff from Design right into Blend. You can import all of your Illustrator files into Design.
  • Right now it’s taking me a long time to do relatively simple stuff, like figuring out how to get stuff laid out inside a list box item. Then again, I was in the car doing this so I was sans-Internet, and I’m sure there are lots of examples out there by now of how to do certain things.

I’ll try and post more updates and I continue to try and figure this all out.

Ode to third party software

Posted on March 8th, 2007 in .NET by Jon Kruger

Third-party tools can be very useful, if not essential, when developing applications. But what I find really interesting is the way people talk about and criticize third-party products. Here are some observations that I’ve noticed over time:

Most developers think that if they had the time, they could do a better job of developing a third party product than the people who actually wrote it. OK, I’ve been guilty of this one too. This probably the same reason that most developers, when given an application or module that they didn’t write, will usually recommended that it be completely refactored and rewritten. We don’t always understand code that we didn’t write. This, however, doesn’t make the code bad.

Have you ever tried and develop a base control for your team to use? It’s hard! You create it and people start using it, but then you find something that you could’ve done better, but going back and changing it is really hard because now all of these other people are using it and you might break their code. So I have lots of respect for people who try and write controls that 10,000 people are going to use.

Also, most developers are much quicker to point out the fault of a third party package than they are to point out the good aspects of it. Case in point: CSLA (the business object framework). I worked on a project recently that used CSLA and I liked it. There are a few quirky things about it, but nothing that I couldn’t live with. But almost every time that I have brought up CSLA in a conversation, the person I’m talking to spouts off numerous things that they don’t like about it (usually stylistic things, never “I won’t be able to do what I need to do if I use CSLA.”). So if they don’t like CSLA, what’s their alternative? Almost always you hear, “Oh, I’m just going to write my own business object framework.”

Let’s think about this for a second. Granted, a simple business object framework isn’t that hard to implement; you can get by with just providing ways to do validation, loading, saving, deleting, and dirty state and be OK in some situations. But let’s say you want more complex stuff, like a rules engine. Do you seriously have that much spare time on your project that you have time to develop your own complex business object framework? Man, I need to come work on that project!

My point is not to champion CSLA and tell you that you should always use it in all situations. (I will say this about CSLA though — the project that I worked on that used CSLA was the most well-structured and organized code base I’ve ever worked with, the code was really easy to read, and new people could join the project and figure things out pretty quickly. The developers deserve a lot of the credit for this, but CSLA helped everyone use good coding practices and patterns.) The point is that, in my opinion, just because you have issues with someone’s coding style, their overuse of reflection or generics, or whatever it may be doesn’t mean that you should completely ignore a third party product and go off and write your own! The real question you need to ask is whether or not the software is going to provide business value and help you accomplish your task better, faster, and cheaper.

So next time you have to evaluate third party software, ask yourself these questions:
- Is this software going to provide business value and help me accomplish my task?
- Is something in this software package going to prohibit me from doing what I need to do?

Policy Injection Application Block

Posted on March 3rd, 2007 in .NET by Jon Kruger

The patterns & practices group at Microsoft just announced the Policy Injection Application Block. The basic idea is that you can define a set of policies and handlers that will execute before and after certain policy-enabled methods. This will allow you to perform such tasks as validation, exception handling, authorization, etc. without having to write the same sections of code over and over in every method.

The main benefit (as I see it) is the separation of concerns. How many times have you worked on a project where someone told you, “Make sure you call this method at the beginning of every method that does _____.” or, “Make sure you put this specific code around your code to handle exceptions.”? It’s hard for everyone on a team to remember all of these little tricks, and you also run the risk that people on the team won’t always do everything correctly. My boss always says that we as developers need to “get out of the plumbing business” and write code that actually does something meaningful from a business perspective, and this will definitely help accomplish that goal.

But in reality, the first thing I thought of when I first heard about this was that many people will probably find many ways to misuse and abuse this application block. By giving the people more power, you’re also giving them more power to screw things up. I’m sure there will be some interesting anti-patterns with this application block.

Next Page »