views:

1454

answers:

20

This is a subjective question.

Recently I have been trying to learn NHibernate. The problem with it is at least 2 fold:

  1. mapping xml file that needs to be coded by hand
  2. Entity Class that needs manual coding

While NHibernate is a wonderful framework, but the need to write mapping file and to create entity classes that mimic the database tables are pain in neck to write. There are a few tools that can alleviate this problem, such as Castle ActiveRecord or NHibernate Fluent.

But as much as those tools can reduce code repeatation problem, there are still some duplication code that you have to write, or some decorative attributes that you have to put on. I am now trying some code generation tool that allows me to generate the mapping files and the entity classes straight from the database. To me this is a more effort saving task.

What do you think?

A: 

I think that if the generated code is more or less the same as you would write manually, then go ahead.

If it's well done, you will hardly have to go back and tweak it a couple of months from now. After you get your code generated and make some adjustments, then you'll find peace in that project :P

Seb
+1  A: 

Using code generation to kick start your effort is fine in my opinion. The issue comes when you need to modify the generated code to handle special cases, or when you find your generated code is not what it should be, then finding the person to work on the generated code might be difficult depending on your team. I worked a project recently where the code was generated by one person, and he used his own magic method to do it...He ended up becoming a bottle neck so towards the end we stopped the code generation, and things worked out rather well.

JoshBerke
+5  A: 

It's a double edged sword. On the one hand, it can be a huge timesaver. Look at the size of the stubs that VS generates when you point it at a WSDL file--I'd hate to have to code that up each time I wanted to consume a new web service.

On the other hand, as you point out, you're almost always going to need to subtly tweak the generated code, which can lead to errors if you don't know exactly what you're doing as generated code can be quite labyrinthine. So, I suppose my answer is: get familiar with what's emitted from the code generator first before relying on it.

drewh
A: 

No - why should it be?? If I can get a tool to do the annoying, boring code for me - I can do more interesting stuff in the mean time!

Marc

marc_s
A: 

For an excellent example of generated code that is very extensible, look into the DSL Toolkit that's part of the Visual Studio SDK. One uses it to define your own graphical domain-specific language (which is generated), and much of the behavior can be customized through partial classes and overrides. It's a very powerful combination.


Two notes: .NET does quite a bit of code generation behind the scenes. Regular expressions, XML Transforms, and XML Serializer code are generated on the fly. Of course, the same is true of ASP.NET, and I'd be surprised to find it's not used more than this (I'm thinking about XAML).

Also, I want to say explicitly that the classes generated by the DataSet Designer and by "Add Web Reference" and "Add Service Reference" are all partial classes. You can leave the generated files entirely alone, and still extend the generated classes. See the bottom of Ways to Customize your ASMX Client Proxy for an example of this.

John Saunders
+24  A: 

Generally speaking, you don't want to be editing generated code after it has been generated (particularly if the input to the code generator is complex and/or likely to change).

I find that it's usually OK to use code generation as part of a build process (so the generated code is never under version control).

My experience of "one-shot" code generation (where the code is generated and then tweaked and extended manually) is that it's a source of pain. If you ever want to go back and change the data from which the code was generated, you nearly always end up having to manually merge your custom changes...

Anodyne
+1 to not modifying generated code. I'm in a cycle of manually merging code generated by the Rational Architect web service wizards. Not fun.
DMKing
"the generated code is never under version control". Agreed this is the goal. Don't check in binaries! And generated code might as well be a binary sometimes, in terms of readability...
Steve Jessop
I disagree with the not checking the code into source control bit. It depends if the source of the generated code is under your control, if it's not you want to be able to checkout a release with everything required to build it.
jonnii
@jonnii - Yes, probably I should have drawn attention to that assumption.
Anodyne
+3  A: 

Larry Wall (the creator of Perl) says that the three cardinal virtues are laziness, impatience, and hubris, and that there are good and bad versions of each.

You are exemplifying laziness (the good way) in trying to automate boring and uncreative work. Good for you.

I would try to make sure that I didn't have to tweak generated code, if at all possible, perhaps by providing hooks to add in customizations.

David Thornley
A: 

Code Generation is the best thing according to me because, imagine you have to write 200 classes, good, somehow you wrote a manual code 200 times, great effort, but when its time to realize you made a small mistake, you will need to solve that mistake 200 times !!!

Not only that, many times the silly mistakes like writing == null instead of !=null, and such logical error will never be found in compile time.

With code generation tools you can control huge number of lines, I wrote Erp Objects, which does so much of code generation, 65,000 lines of code for database integration for 400 tables !!, well if there is any bug, we just repair the code generator and go ahead and regenerate !!

You can add automatic documentation for each generated code, you can indent and keep it clean and beautiful, if you find a way to optimize, you will not have to repeat your code.

Please note, .NET 4.0 is coming with inbuilt code generation and compilation facility, well world is moving towards generation, because the generated code runs faster then interpreted and generic logic.

Akash Kava
Shameless -ve voters, are you afraid to comment?
Akash Kava
A: 

I think the question of whether or not to use code generation depends on what your goals are with the code.

Your example of a data access layer is a good one. Your problem with NHibernate is that you have to generate the domain classes yourself. If your domain classes map directly to the database schema, then this is not a problem. However, one of the strengths of NHibernate in this scenario is precisely that you CAN define your own domain classes, and that they do not have to map precisely to the database layer. That means you can tweak your DB layer later on and the only code you have to change is the mapping file. If you used code generation, you'd probably have to tweak a lot more code, and the tweaks would not always be as straightforward as the tweaks to the mapping files would have been.

Chris Shaffer
If your domain classes map directly to the database schema, then this is a problem.--- I dont get what you mean, why you said that this is a problem?
Ngu Soon Hui
Oops, missed a "not". Thanks!
Chris Shaffer
+7  A: 

Code generation is a good thing when done right, but is far too frequently done wrong.

IMO, code generators must be smart enough to handle changes to the generated code. Back in the .NET 1.0 days, even the shiny new Visual Studio .NET code generators could do that -- within reason. With .NET 2.0 we got partial classes to make it even more easy.

And yet, there are still some generators out there that are quite incapable of working more than once.

My rules for "good" code generation:

  • The code should be generated within the IDE for which the code is generated. No third-party executables. Typically this is a Visual Studio plugin, but this rule applies to other languages as well.
  • The code generated should provide clear and easy extension capabilities.
  • The code generated should be otherwise invisible to the developer.
    • In other words, the developer should only use the designer to modify generated code.
Randolpho
Good post. Partial classes are a great way to simplify the clear separation of generated and hand-written code, but it only works well if you don't have to touch the generated code ever.
OregonGhost
Randolpho - I love your answer and am curious to what you use in Visual Studio.
Mario
@Mario: unfortunately, very little. Even some of the default designers bother me so much I prefer to go in and write it by hand.
Randolpho
+2  A: 

Code generation is fine as long as you understands what is being generated or when it has replaced a default value with a custom one(case in point)
For e.g. This is part of the nhibernate mapping generated by MyGeneration
Why is there a

IsChanged

property

/// <summary>
/// Returns whether or not the object has changed its values.
/// </summary>
Public virtual bool IsChanged { get; private set; }

Will it change?,When will this change? and what happens when it changes.

A hand crafted nhibernate entity class will most probably have only column properties and constructors.

These are all scenarios you will run into, especially in an enterprise world where there are hundreds of programmers working on a project and mediocrity a fact of life.

Another concern is control granularity, especially when it’s part of build and one fine day you realize that it should be fine tuned.

Fortunately frameworks like .net allow for partial classes, extension methods etc which help you deal with situations this.

Cherian
A: 

I've absolutely nothing against generating code that doesn't need to be modified: that's what compilers do :-)

Using tools to save typing that you would have done anyway, is also fine. At the very simplest level of this, function name auto-completion by the IDE is "code generation".

Problems can arise when you generate some fairly complex code, then make substantial changes by hand, then later want to repeat it with the latest version of the code generator. In general it's very hard to disentangle your changes and apply them to the new version. diff3 (or however your source-control does merges) might work, but is far from guaranteed to help at all.

The same applies when you make major changes to open source code - if you can't encapsulate your responsibilities into separate files with minimal changes to the base, then every time a new release comes downstream you have a bunch of error-prone drudge work on your hands. So think of it that way - your project relies on source you didn't write. If there's any chance you'll want to incorporate changes to that code, you have to isolate it properly.

Rule of thumb is that anything done automatically should be repeatable. Code generation isn't repeatable if there's any thought required to turn what it produces into what you want.

Steve Jessop
+1  A: 

We couldn't function at nearly the level we do without code generation. It's ubiquitous.

Without code generation we'd be manually setting bits in wide microcode words to gate things to the right bus.

What you really me is, "Is it OK for me to take some of this awesome power for my very own use?"

To which I'd reply "Sure, knock yourself out. Just remember 1) with great power comes great responsibility and, 2) only use it for good, never for evil."

MarkusQ
I disagree, good OO design and practices can *usually* completely eliminate the need for generated code. The more well-designed a project is, the less it will have to lean on something like code generation. Code generation is like a sledgehammer, sometimes you need a scalpel.
Mark Rogers
@m4bwav -- Dude, what do you think your OO languages are doing under the hood? Saying good OO languages can eliminate the need for code generation is like saying a good car can eliminate the need for engines.
MarkusQ
Right, but doing "under the hood" is going to better than doing it on top of the hood, to continue the analogy.
Mark Rogers
Right, but doing it "under the hood" is going to be much better than doing it on top of the hood, to continue the analogy. And far more maintainable.
Mark Rogers
It depends. If you're writing a compiler, you'd better be able to do code generation. Or if you're building a framework like rails, or a dynamic ajax application. Or doing functional programming. Or anything else for that matter, apart from just using the code generation tools built by others.
MarkusQ
Hmm, I guess I still totally disagree. But I'll remove my downvote, because maybe you have a point, and I just don't understand it yet.
Mark Rogers
A: 

Code Generator can save you some valuable time, but please keep in mind if you start to generate huge amounts of code, that also means your code is not DRY, meaning a lot of repetition. This could introduce problems for code maintenance, and degrade the elegance of your code.

If you find yourself generating a lot repeated blocks of code or similar code, try to find a better way, such as Class Factories / Runtime code generation. It takes longer to write, but it's more fun and more elegant. Makes maintenance easier as well.

Lastly, if you have the freedom to choose your language, you could try ruby's ActiveRecord (A rails package), or DataMapper, or Sequel. They are all excellent ORMs that requires minimum configuration.

Aaron Qian
Generating a lot of repeated code is not a problem even if you follow the DRY principle. Remember that you only need to change one thing (the input to the code generator) to update all the code. So code generation (if done correctly) is following the DRY principle.
MB
+1  A: 

If you are not using code generation in your development to some extent, then you are doing more work than you should. Code generation used properly will improve the quality of code, make the project more maintainable, and help you deliver the solution faster with fewer bugs.

I have written 3 code generators, but currently I use Code Smith. Sometimes I use the NETTiers templates. Sometimes I use my own.

I don't really care which generator you use. CodeBreeze, CodeSmith, LLBLGen, xslt files, etc...

Get one, learn it, love it.

EVERY project I have been on for 10 years or more, included some generated code.

Start here: <http://www.dotnetrocks.com/default.aspx?showNum=63>

<http://www.dotnetrocks.com/default.aspx?showNum=304>

<http://www.dnrtv.com/default.aspx?showNum=77>

<http://www.dnrtv.com/default.aspx?showNum=133>

<http://www.nettiers.org/Home.ashx>

Gotta run. Enjoy.

Bobby Ortiz
A: 

No. Code-gen is neither good nor evil. It's simply a tool. If you use it well, it can save you immeasurable time. If you use it poorly, on the other hand, it can end up costing you that very same immeasurable amount of time.

One little tidbit, if do do code-gen in an oo environment, I'd suggest you wrap the generated classes if you want to extent them from the generated ones.

Aaron Palmer
+1  A: 

I agree with most of the commentors that code generation is neither good nor evil. I have seen generated code be a great source of pain as well as a pragmatic solution to some problem at hand.

BUT in your case I would definitely check out one particular feature of Fluent NHibernate: auto mapping! More info here.

Once set up, you can create persistent classes that are automagically mapped to the db by writing nothing more than your entity classes. This is the right way around - defining your domain model in the database is kind of icky (at least if you can avoid it).

My 2 cents, at least.

mookid8000
A: 

Lots of good answers.

Solving problems by having programs write programs is a great idea, but there is no great idea that can't be badly used.

The basic question I ask of a code generator is "Do I understand what it's doing?".
If I don't, then it will probably not help me.

Mike Dunlavey
A: 

I use code generators every day. It has dramatically reduced the time I need to write the boring/tedious part of the application.

I can highly recommend using Ruby as a code generator tool. I generate both C++ and C# code from Ruby. The input to the code generator is a simple internal DSL.

MB
+2  A: 

Build-time code generation is bad because:

  • it's way harder to maintain - a new programmer looking at the project may waste a week understanding that some code is actually generated;

  • it requires a full build to be generated, and in a development environment you don't want to go through a full-build often;

  • when an exception occurs in a generated code, you're stuck;

  • it requires extra (often complex) SCM settings in order to ignore it;

  • you cannot modify it even if you want, because it will be overridden on the next build;

  • changing the definitions from which the code is generated may turn out to break the codebase, but this is not found until later (i.e. you may be developing happily while having broken code).

Bozho