Input requested: #if vs partial class

Input requested: #if vs partial class

Old forum URL: forums.lhotka.net/forums/t/5151.aspx


RockfordLhotka posted on Thursday, July 24, 2008

As we work on CSLA Light (CSLA .NET for Silverlight), there's (at least) one continuing point of debate in the team - so I thought I'd gather more input.

One goal of CSLA Light is to allow the majority of your business code to be the same in Silverlight and .NET. The data portal runs between the two platforms, and your business objects literally move from .NET to Silverlight and back again. Very cool stuff!

This means that the same physical class file is included in two projects - a Silverlight Class Library and a .NET Class Library. We do this using the ability in VS to "Link" a file from one project into another, so the file exists once, but is in two projects. Pretty easy once you do it.

That all works nicely - for code that is 100% compatible with CSLA Light and CSLA .NET. This includes your property declarations, validation rules (mostly) and authorization rules.

This does not include your factory methods (usually) or your data access code. Silverlight doesn't even have the data access technologies available on .NET, so that code simply can't compile or work in Silverlight.

What this means is that, for a given business object like CustomerEdit, you could have three types of code:

  1. Shared code that runs in Silverlight and .NET
  2. Code that only runs in Silverlight (rare but possible)
  3. Code that only runs in .NET (data access at least)

So that linked class file will at least contain the shared code.

Using compiler directives like "#if SILVERLIGHT" and "#if !SILVERLIGHT" the linked class could contain all three types of code. It is just that some of it won't compile on Silverlight or .NET obviously.

Another solution is to use partial classes. In this case there'd literally be three different files. The linked one with the shared code, a partial class in the Silverlight Class Library for the SL-only code, and a partial class in the .NET Class Library for the .NET-only code.

Either solution gets the same end result - all three types of code are there. The compiled results are the same either way.

We're really just talking about coding style - which is easier to understand, read, and explain?

Would you prefer to see all your code in one file, with sections blocked out with #if statements?

Or would you prefer to split your code into three files, each one with clear meaning?

(please note that CSLA Light will support either model - but all our examples, etc will be in one mode or the other - we're just trying to figure out what to "recommend" as the best approach)

Your input is very welcome!!

ajj3085 replied on Thursday, July 24, 2008

I think I'd prefer partial classes. 

You could have Person.cs, Person.SilverLight.cs and Person.Net.cs.  All relevant code is tucked away in an easy to find spot, vs. being intermixed with compiler directives, which seem messier to me.

FatPigeon replied on Thursday, July 24, 2008

I would vote for partial classes, each file is kept as simple as possible, and you can tell from the file name where the code will end up rather than trying to keep track of where you are in the file in relation to the compiler directives.

decius replied on Thursday, July 24, 2008

I, personally, would also definitely prefer partial classes.

ShawnCamp replied on Thursday, July 24, 2008

Partial Classes are much easier to read and manage than Compiler Directives in my opinion.  Although having 3 different files could be a little confusing, I still think its a better approach.

chrisghardwick replied on Thursday, July 24, 2008

I would prefer partial classes.

dlambert replied on Thursday, July 24, 2008

Cast another vote for partial classes.

paupdb replied on Thursday, July 24, 2008

I'll go against the grain here and say that compiler directives would be my preferred approach.

I've been looking through the test harness for CSLALight (which uses the partial class approach) and when trying to follow the code from SL to .Net for a single business object class, I have to have 2-3 tabs open in VS.  After looking at a few business objects, my VS tabs were pretty crowded.

If you structure your code well enough - i.e. use regions and keep your SILVERLIGHT and !SILVERLIGHT sections together, then you have the advantage of all the code being visible in one screen in VS - i.e. just like a normal CSLA.Net class file. 
Such seperation can be enforced easily enough using code templates.

This argument seems semantically similar to an argument one can have about seperating data access code out of your CSLA.Net class file into a partial class. 
Instead the recommended approach for CSLA is to have it all in one class file and use regions and good coding structure to keep the logical seperation clear.

Why go in a different direction with the compiler directives?

Another point is that using partial classes will cause projects to bloat by roughly a factor of 2 in terms of files listed in the VS solution explorer. 
With the size of application I am working on - probably going to have in the order of 300+ business object classes when we done - minimising the number of project files is a key concern for us in terms of readability and management of the solution structure.

Lalit replied on Friday, July 25, 2008

My vote for partial class to make life easier. :)

mr_lasseter replied on Friday, July 25, 2008

I like the idea of being able to use the same code for both .Net and Silverlight, but doesn't what you are asking seem a bit hackish?   It might be a slippery slope...

RockfordLhotka replied on Friday, July 25, 2008

mr_lasseter:
I like the idea of being able to use the same code for both .Net and Silverlight, but doesn't what you are asking seem a bit hackish?   It might be a slippery slope...

I don't think so.

We're working very hard to make sure the property declaration, validation rules and authorization rules concepts from CSLA .NET appear the same in CSLA Light. Specifically so those regions of your objects can run in both environments.

My goal is to enable mobile objects between SL and .NET, and that means as much shared functionality as possible.

Yes, it is possible for someone to write some SL-only or .NET-only code in there, but the dual-project with linked files technique tends to catch that immediately when you build the solution. And if you stick with 'standard' CSLA property declarations and other techniques this is not likely to start with.

The only place you can get into trouble is with business or validation rules that interact with the data portal. This is because the SL data portal is only asynchronous, and that means this type of validation rule must be async too.

But we've added an async data portal and async validation rules to CSLA .NET too, so even that code will be common between the two environments.

In the end, only your constructor, factory methods and data access code are different between the two environments - which loops us back to the #if vs partial class question.

And even there, either technique works great. We're using some of each in testing (got to make sure). But there'll be actual samples in the near future, and they need to be consistent - one way or the other.

JoeFallon1 replied on Friday, July 25, 2008

I already have "too many files" in my app.

I have a code gen layer and then a layer of derived classes with a possible 3rd layer of more derived classes. If I have to triple each of them in order to support Silverlight, that could get out of hand. So I am leaning toward the compiler directives and keeping things in their proper regions of the BO.

If I only had a single set of BOs then I would definitely prefer partial classes but I don't so I won't.

Joe

 

Geeky replied on Thursday, February 19, 2009

I know this is a bit late - only just started on CSLA Light but I would favour complier directives.  IMHO partial classes are just a hack by M$ to enable designer files ;-)  A file should contain one type and one type should be in one file.

rfcdejong replied on Wednesday, February 10, 2010

I see many people are voting for partial classes, i agree for regular csla code. But I disagree when using the objectfactory pattern since in that case there won't be any data access in the shared business classes.

I do hate the fact that there will be ALOT more classes. We have a generated project with around 3000 classes and it takes ages to get from TFS and to work with in Visual studio, Visual studio often crashes when we include the project and building isn't any fun.

cdkisa replied on Wednesday, February 10, 2010

I vote partial classes. It would be like an nTier class (business logic, data access logic, whatever else logic).

ajj3085 replied on Wednesday, February 10, 2010

For those just joining in, this "vote" happened almost a year and a half ago, so I'm not sure how much impact further voting will have.  Smile

RockfordLhotka replied on Wednesday, February 10, 2010

Very true Andy Big Smile

I can share what we learned from building and maintaing CSLA .NET for Silverlight over the past quite-a-few months (it has been almost 2 years - wow!!)

We did some of each - some compiler directives, some partial classes.

In the end, at least within the framework, the compiler directive approach is far superior. Having class code spread into 2-3 different files makes it too hard to find and maintain bits of code over time. And it makes it harder to manage the file linking.

Now with CSLA 4 there's csla.client, csla.core and csla.silverlight - so we're talking about the potential for 1 core file and 3 partial files, which would just compound the challenge.

There are obviously differences between building business apps and frameworks, but from a framework perspective CSLA is shifting (slowly) entirely to a #if solution and away from the partial class approach.

However, for business solutions I think partial classes are a very workable solution. The reason for this is that I use them to separate out entire regions of code (like the DataPortal_XYZ methods and synchronous factory methods). There's very clear delination within the standard business class structure as to which code is server-only and which is shared. So, unlike framework code, the results are very clear.

The problem with framework code is that the differences between SL and .NET are often very subtle, and we're changing just one line of code, or one part of a method implementation. That's very different from the typical business class scenario, and doesn't lend itself well to partial classes...

ajj3085 replied on Thursday, February 11, 2010

That's a great insight.  I haven't delved into SL yet, but I"m hoping to in the very near future.

For developing the business library, I was leaning toward the partial class method, and its reassuring to hear that it sounds like the way to go. 

Copyright (c) Marimer LLC