Saturday, April 12, 2008

Someone on the CSLA .NET discussion forum recently asked what new .NET 3.5 features I used in CSLA .NET 3.5. The poster noted that there are a lot of new features in .NET 3.5, which is true. They also included some .NET 3.0 features as "new", though really those features have now been around for 15 months or so and were addressed in CSLA .NET 3.0. CSLA .NET 3.0 already added support for WCF, WPF and WF, so those technologies had very little impact on CSLA .NET 3.5.

My philosophy is to use new technologies only if they provide value to me and my work. In the case of CSLA .NET this is extended slightly, such that I try to make sure CSLA .NET also supports new technologies that might be of value to people who use CSLA .NET.

While .NET 3.5 has a number of new technologies at various levels (UI, data, languages), many of them required no changes to CSLA to support. I like to think this is because I'm always trying to look into the future as I work on CSLA, anticipating at least some of what is coming so I can make the transition smoother. For example, this is why CSLA .NET 2.0 introduced a provider model for the data portal - because I knew WCF was coming in a couple years and I wanted to be ready.

Since CSLA .NET already supported data binding to WPF, Windows Forms and Web Forms, there was no real work to do at the UI level for .NET 3.5. I actually removed Csla.Wpf.Validator because WPF now directly supplies that behavior, but I really didn't add anything for UI support because it is already there.

Looking forward beyond 3.5, it is possible I'll need to add support for ASP.NET MVC because that technology eschews data binding in favor of other techniques to create the view - but it is too early to know for sure what I'll do in that regard.

Since CSLA .NET has always abstracted the business object concept from the data access technique you choose, it automatically supported LINQ to SQL (and will automatically support ADO.NET EF too). No changes required to do that were required, though I did add Csla.Data.ContextManager to simplify the use of L2S data context objects (as a companion to the new Csla.Data.ConnectionManager for raw ADO.NET connections). And I enhanced Csla.Data.DataMapper to have some more powerful mapping options that may be useful in some L2S or EF scenarios.

LINQ to Objects did require some work. Technically this too was optional, but I felt it was critical, and so there is now "LINQ to CSLA" functionality provided in 3.5 (thanks to my colleague Aaron Erickson). The primary feature of this is creating a synchronized view of a BusinessListBase list when you do a non-projection query, which means you can data bind the results of a non-projection query and allow the user to add/remove items from the query result and those changes are also reflected in the original list. As a cool option, LINQ to CSLA also implements indexed queries against lists, so if you are doing many queries against the same list object you should look into this as a performance booster!

So all that's left are some of the language enhancements that exist to support LINQ. And I do use some of them - mostly type inference (which I love). But I didn't go through the entire body of existing code to use the new language features. The risk of breaking functionality that has worked for 6-7 years is way too high! I can't see where anyone would choose to take such a risk with a body of code, but especially one like CSLA that is used by thousands of people world-wide.

That means I used some of the new language features in new code, and in code I had to rework anyway. And to be honest, I use those features sparingly and where I thought they helped.

I think trying to force new technologies/concepts/patterns into code is a bad idea. If a given pattern or technology obviously saves code/time/money or has other clear benefits then I use it, but I try never to get attached to some idea such that I force it into places where it doesn't fit with my overall goals.

Saturday, April 12, 2008 3:11:52 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [2]  | 

 Friday, April 11, 2008

VS Live Orlando VS Live Orlando is coming up soon, and I'll be speaking at the event.

I'm giving a presentation on the use of OO concepts, WCF services and Silverlight working together to build compelling web applications.

And I'm giving a full-day workshop covering a broad range of .NET technologies, focused on transitioning from the .NET 2.0 world forward into the .NET 3.5 world. Not surprisingly, I use CSLA .NET as part of this workshop, though the primary focus is on making sense out of all the different technologies you might use for creating your applications.

As a track chair and speaker for VS Live, I am able to provide you with a special discount code. Register for VS Live using the code SOLHO and save $300!

Friday, April 11, 2008 8:41:10 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

 Thursday, April 03, 2008

CSLA .NET version 3.5 for .NET 3.5 and Visual Studio 2008 is now available for download from www.lhotka.net/cslanet/download.aspx. This version of CSLA .NET includes support for LINQ and provides substantial code reduction (often around 40%) when coding your business objects.

Check out the official launch announcement on DotNetRocks!

If you are using .NET 2.0 or 3.0 with Visual Studio 2005 or 2008 then you'll want to use CSLA .NET version 3.0.4. Version 3.0.4 includes some data binding bug fixes over version 3.0.3, and it works with .NET 2.0 or .NET 3.0. It is also available from the download page.

As always, questions and comments are welcome on the forum at http://forums.lhotka.net.

Thursday, April 03, 2008 8:27:11 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [4]  | 

 Monday, March 24, 2008

Dunn Training is holding a three day CSLA .NET training class in Toronto, May 5-7. Dunn's three day class is a great way to jumpstart your use of CSLA .NET, and Toronto is a fun city, so this is a great opportunity!

For details go to http://www.dunntraining.com/training/schedule.htm.
Monday, March 24, 2008 8:50:29 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

 Monday, March 17, 2008

n579576978_702761_9418Microsoft Tech Ed 2008 is coming up in early June. This year they are splitting it into two parts: IT Pro and Developer, each of which gets a week. I think this is a good move, as it allows the Developer week to be focused on topics developers care about. They've done this for a couple years now in Europe and it has been successful there.

The developer week is June 3-6.

I'm a co-chair for the Developer Tools track, which covers Visual Studio, all the languages and related topics. I think we put together a great set of speakers and topics in this track, so I'm very excited about it!

I'm also one of the featured speakers, and you can see details about all the featured speakers in a nice little Silverlight app.

Monday, March 17, 2008 7:26:55 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [1]  | 

 Sunday, March 16, 2008

I recently participated in a webcast covering SOA, REST and various related topics. You can listen to it here

http://www.slickthought.net/post/Minneapolis-Developer-Roundtable-Podcast---Talking-REST.aspx

Sunday, March 16, 2008 6:32:37 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [1]  | 

I have a question (helping a colleague do some research) for all .NET VB developers.

Do you use late binding in VB? If so, how/why do you use it? What are the scenarios where you find it of value?

I'll start this off with my own observations:

I use late binding when getting data of a given shape from unknown types.

For example, you can write a nice bit of reusable data access code that accepts data from a web service, LINQ object, etc. by using late binding. You can’t easily do this without late binding in fact, because the types of the objects are different even though their shapes are the same.

That dynamic interface concept that got dropped from VB9 would address this issue in a better way, but late binding makes it work too.

I also use late binding when creating some generic types. There are cases where generics and casting are problematic, but converting a value to type Object first allows you to do a cast or operation that wouldn’t otherwise be allowed. I don’t know if this is “late binding” as such, but it is a useful technique!

I have used late binding when dynamically loading an assembly for interaction. Ideally you’d require the assembly author to implement one of your interfaces, but that’s not always possible, and late binding is a particularly nice way to get “polymorphic” access to multiple assemblies that you don’t control.

What about you?

Sunday, March 16, 2008 2:56:16 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [6]  | 

 Friday, March 14, 2008

Sometimes you just can't catch a break...

About two weeks ago my server's motherboard went bad. That's no fun, but www.lhotka.net is running in a virtual machine (VM) on Virtual Server, so it was relatively easy to get it back running on my desktop workstation. Not ideal, but a temporary workaround. And since I was heading to Las Vegas for MIX 08 I didn't need the desktop anyway.

Last weekend my good friend (and hardware guru) Rick came over and we confirmed it was the motherboard, and purchased replacement parts. A shiny new Q6600 CPU and a motherboard to match. Now my physical server is a quad core machine, and that's very cool. Though I am running Windows Server 2003 64 bit and Virtual Server 2005 R2 as the host, so the VM still can't use more than one CPU :(  Still, each core of the new CPU is much faster than the previous single-core CPU.

On Monday I got the VM copied off my desktop and onto the new server. All seemed to be working, which made me happy. And I blissfully flew off to LA to spend the week with a client.

Only to find out that there's a problem! The VM uses a virtual network adapter that is attached to the host's real network adapter. For some reason the VM periodically sees the network adapter become "unplugged". Which of course it is not. The physical NIC is working fine, but the VM is losing it. Manually disabling/enabling the virtual NIC fixes the problem, but this happens every few hours (so if you've noticed www.lhotka.net offline a lot the past few days this is why).

Also, my System event log was (and is) filling up with "The netcard driver failed the query for OID_GEN_LINK_SPEED", related to the QoS service.

Googling turned up a few people who've had the same problem. But no serious answers. Apparently people solved the problem but never posted their solution in any coherent manner. More googling, and then more... Eventually I found some tidbits of info here and there. Things to try:

  1. Disable the QoS service on the virtual NIC (had no effect for the original poster or me - though it does stop the event log entries)
  2. Remove the virtual NIC and restart the VM so it redetects the NIC (didn't work for the original poster, nor for me)
  3. On the host, uncheck the virtual server support on the real NIC, reboot the host, re-check the virtual server support on the real NIC, reboot the host (I don't know if it helped the original poster, but it didn't help me)
  4. I noticed that the host didn't have the Windows Firewall turned on, so today I turned it on (I don't know yet if that had any impact, but I feel better having done it)
  5. Uninstall Virtual Server, then reinstall it (don't know if it worked for the original poster, and haven't tried this yet)

Interestingly enough, enabling the firewall on the host might have had an impact. The VM has been successfully running for around 5 hours now. I am rather doubtful that this is the problem, but maybe I'll get lucky. I still can't enable the QoS service without flooding the event log with errors though...

To add insult to injury, as I was messing with all this today (running on 3 hours of sleep and having just flown back from LA), some spammer decided to target my wife's blog for pingback spam. It is like a denial of service attack - they are sending 4-5 post requests to her blog every second. And dasBlog is clearly not capable of handling that kind of volume. So the VM pegs at 100% CPU, the disk is thrashing, everything is incredibly slow, and they somehow got past the fact that she has pingbacks turned off and managed to load hundreds of them into her blog...

The dasBlog cleaner utility got rid of about 70% of them, and I wrote a quick VB app to clean the rest (the LINQ to XML support in VB is so incredibly awesome!!!), and we tweaked some more settings so I don't think they can get the pingbacks to record anymore. But they are still trying, so now it really is a DOS attack.

Do I think spammers should go to prison? Absolutely. They cause direct, tangible harm, and they should be deprived of their ability to harm or interact with normal human beings if at all possible. They are like mass muggers.

What puzzles me is that the URLs they were spamming into the blog don't actually go anywhere. Each one was unique and semi-random. I can't figure out the motivation behind this, since they clearly can't get any value out of a URL that doesn't go anywhere can they?

So maybe they shouldn't to prison. Maybe they should be locked up in a looney bin somewhere?

Anyway, I very much doubt this is the end of the saga. Though I think I've blocked the pingbacks, they continue to pound the server. And I expect the server's NIC to disconnect any time now - in which case I'll try the uninstall/reinstall of Virtual Server in the hope that solves the problem...

I really, really hate computers sometimes...

Friday, March 14, 2008 6:35:51 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [6]  | 

 Monday, March 10, 2008

In a previous post I talked about the new property declaration syntax options in CSLA .NET 3.5. When it comes to child objects, if the shortest form is used then CSLA will pretty much completely take care of all parent-child object interaction so you don't have to do it by hand. This is a tremendous code savings!

So declaring a child property like this:

private static PropertyInfo<ChildList> ChildListProperty =
  RegisterProperty<ChildList>(new PropertyInfo<ChildList>("ChildList");
public ChildList ChildList
{
  get { return GetProperty<ChildList>(ChildListProperty); }
}

allows CSLA to manage the child object. Of course you do need to create the child object somewhere, such as in the DataPortal_XYZ methods:

[RunLocal]
private void DataPortal_Create()
{
  // initialize other fields here
  LoadProperty<ChildList>(ChildListProperty, ChildList.NewList());
  base.DataPortal_Create();
}

private void DataPortal_Fetch(...)
{
  // initialize other fields here
  LoadProperty<ChildList>(ChildListProperty, ChildList.GetList(this.Id));
}

Another option is to use a lazy loading scheme. There are a couple options in how you can use lazy loading. You can avoid the DataPortal_Create() implementation by just creating a new, empty list - and I do this almost all the time now:

private static PropertyInfo<ChildList> ChildListProperty =
  RegisterProperty<ChildList>(new PropertyInfo<ChildList>("ChildList");
public ChildList ChildList
{
  get
  {
    if (!FieldManager.FieldExists(ChildListProperty))
      SetProperty<ChildList>(ChildListProperty, ChildList.NewList());
    return GetProperty<ChildList>(ChildListProperty);
  }
}

With this approach you still need to load the child data in the DataPortal_Fetch() method. The only thing this does is eliminate the need for the code in DataPortal_Create() - which often means you don't need DataPortal_Create() at all.

Another option is to truly lazy load the object by calling a factory method that actually loads the object with existing data:

private static PropertyInfo<ChildList> ChildListProperty =
  RegisterProperty<ChildList>(new PropertyInfo<ChildList>("ChildList");
public ChildList ChildList
{
  get
  {
    if (!FieldManager.FieldExists(ChildListProperty))
      SetProperty<ChildList>(ChildListProperty, ChildList.GetList(this.Id));
    return GetProperty<ChildList>(ChildListProperty);
  }
}

Obviously this requires that the ChildList class implement a GetList() factory that calls the data portal so it can be loaded independently from its parent. This is different from the first example, where GetList() would use the new child data portal support (or could be implemented the old 3.0 way). I'll discuss the new child data portal support in a future blog post.

If you use lazy loading, CSLA will automatically ensure that the newly created child has its edit level set correctly and that all data binding events cascade appropriately.

in all cases you no longer need to write code in a parent object like this:

protected override bool IsDirty
{
  get
  {
    return base.IsDirty || _childList.IsDirty;
  }
}

protected override bool IsValid
{
  get
  {
    return base.IsValid && _childList.IsValid;
  }
}

Nor do you need to do any hooking of child object events like PropertyChanged or ListChanged - that's all automatic as well.

Monday, March 10, 2008 10:15:41 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [3]  |