This is a killer feature of TeamCity against other CI servers, I believe.
TC allows you to test your changes before committing them to the Source Control Repository, which means that you don’t have to worry about breaking the build, because you won’t :)
I needed this in order to try a fix that I had for an issue in NH, it worked on my machine but not sure if it works on another one.
Krzysztof Kozmic told me in the same evening that he’s going to try a fix against DP with personal build, and I thought it was a great idea!
Then it runs your changes on one of the build agents.
There we go! Patch didn’t break anything (even though it may not be how it should be)
Keep up the good work, JetBrains!
This feature of SVN is very handy. After you build your projects, there will be dlls in bin folders etc which you don’t want to commit.
Using svn:ignore property of SVN, you can eliminate the possibility of committing those files!
As many other things, I learnt this from NH :)
If you are not familiar with the Code Contracts library which is coming out of Microsoft R&D labs, you need to check this pretty cool little library out. As of Vs2010/.Net 4.0 this library will be making the jump out of the R&D labs.
Over the next few blog posts we will be taking a look at the topics below.
In this post we are going to take a look at what I think is one of the coolest features of the Contracts Library. The concept of Object Invariants.
What is Object Invariant validation?
This part of the library ensures that when the state of an object is changed that the object remains in valid state. If the state of the object is to become invalid then your contract would fail and this would be an issue.
Imagine you have a class called ReportCard, this class is used by a timekeeping system and is used to store instances of daily report cards (a daily report card holds the time/hours worked for that employee). We want to setup a rule which says that depending on the employee type they are not allowed to work > 40 hours (the actual number is not important). We also want to setup the ability to ensure they do not work < 0 hours.
Prior to code contracts you would need to create your state checking method and then place calls to the validator at location where the state changes. This is both tedious and error prone because as your add more code (hopefully you follow the Open/Close principle and extend the class not keep piling on new code, but that is a different post) you have to remember to add the state checking logic. With invariants you do not need to do that. All you need to do is below.
[ContractInvariantMethod] public void EnsureReportHoursIsInValidRange() { Contract.Invariant( EmployeeID > 0 ); var totalHours = TotalHours(); // Calcs total hours Contract.Invariant(totalHours >= 0); Contract.Invariant(totalHours <= 40); }
Taking a look at this code there are a few things you should know
Here is the same code above, but this time POST code weaving.
public void AddDailyReport(DailyCards dailyCards) { this.DailyReportCards.Add(dailyCards); this.EnsureReportHoursIsInValidRange(); } [ContractInvariantMethod] public void EnsureReportHoursIsInValidRange() { if (!this.$evaluatingInvariant$) { this.$evaluatingInvariant$ = true; try { __ContractsRuntime.Invariant(this.EmployeeID > 0, null, "EmployeeID > 0"); double num = this.TotalHours(); __ContractsRuntime.Invariant(num >= 0.0, null, ""); __ContractsRuntime.Invariant(num <= 40.0, null, "totalHours <= 40"); } finally { this.$evaluatingInvariant$ = false; } } }
The key thing to notice when looking at the reflected code is how the weaver added the call this.EnsureReportHoursIsInValidRange(); in the AddDailyReport() method.
2 Things to watch out for when utilizing the Object Invariant
Till next time,
A few weeks back I sat down with Larry Clarkin to record an episode of the Thirsty Developer (a podcast that he and Dave Bost put out) prior to my doing my SOLID session with the WI-Ineta group. Larry and I sat down at a local starbucks to chat about the session as well as just talk shop (Dave was off on assignment some place, but was there in spirit).
Well, Larry went off and actually released the episode (hey, when you chat with me the quality mileage may vary :) ) back a week or so ago while I was on a 2 week hiatus from the net (1 week vacation and 1 week of client visits for work) so I am a little behind in making the announcement about this.
Anyway, if you want to listen to our conversation you can check out here. I hope you like it and I am looking forward to sitting down with them in the future to chat again.
Also, if you do not currently subscribe to their RSS feed I would strongly suggest you give them a listen, they are great guys and a ton of fun
Quite often there is a fear that surrounds open source tools and frameworks. For most shops the deciding factor against open source software is the apparent "risk" that is associated with a framework/tool that is not attached to any business entity.
In this post I want to share an interaction that occurred this last weekend to show you that the open source ecosystem is alive and very healthy. And while I won't go so far as to say the "risk" doesn't exist (you have to come to that conclusion on your time when your own fears are allayed) I do hope that this post puts some of those fears to rest.
Saturday morning before I went off to work there was a question posted to the RhinoMocks mailing list (for those who don't know RhinoMocks is an open source mocking framework). Before the end of the day the problem was resolved to a satisfactory conclusion. The "solution" (I put in quotes because there appears to be a bug but at least now we know there is a bug...hence "solution"). The result is not as important as the events that transpired to reach that conclusion below is the timeline.
12:22 AM - Kenneth posts the problem he is encountering 6:53 AM - I respond on the mailing list back to Kenneth with my findings and let him know that I will get some experts in DynamicProxy involved 6:56 AM - I enlisted the help of Krzysztof Kozmic on twitter (Krzysztof is a committer on DynamicProxy by Castle as has a great tutorial series on Dynamic Proxy) 8:38 AM - Fellow Devlicious blogger Tuna Toksoz (also a committer on the Castle project) hopped on the case and reported his findings 9:22 AM - Krzysztof responds to Tuna's findings reporting back on the root cause 10:23 AM - Kenneth reported back with feedback of Tuna's fix
12:22 AM - Kenneth posts the problem he is encountering
6:53 AM - I respond on the mailing list back to Kenneth with my findings and let him know that I will get some experts in DynamicProxy involved
6:56 AM - I enlisted the help of Krzysztof Kozmic on twitter (Krzysztof is a committer on DynamicProxy by Castle as has a great tutorial series on Dynamic Proxy)
8:38 AM - Fellow Devlicious blogger Tuna Toksoz (also a committer on the Castle project) hopped on the case and reported his findings
9:22 AM - Krzysztof responds to Tuna's findings reporting back on the root cause
10:23 AM - Kenneth reported back with feedback of Tuna's fix
Ultimately, as I mentioned earlier the fix was that it was found that RhinoMocks "relies on the buggy behavior, hence the error" (Krzysztof's words). Again the result here isn't what is important but rather the journey. Often people fear the support ecosystem around open source software but the exchange above and the players involved should give you some bit of confidence in the support of open source. It is worth pointing out that all of this happened on a Saturday, something you'd pay a premium for in a closed source model.
Whatever your roll in the software world is, one aspect you have to consider when choosing any solution is risk. The traditional thought has been that with commercial software the support would be better when backed by a reputable name. I think the exchange showcased above demonstrates that support for open source software can compete (and potentially surpass) support that any commercial piece of software could offer. Keep that in mind the next time you are evaluating commercial software versus open source software.
Today I was reading the latest one of the many excellent blog posts Patrick Smacchia has put out on the topic of code metrics and caring for your code's quality.
The passion this guy has for that topic is such that he has created the best tool for analyzing your code. But he doesn't stop there. He wants to make sure we understand what is going on behind the seemingly magic CQL queries that ship with NDepend. He wants you to understand your code's DNA; with the added bonus that you can actually improve that DNA.
That's Science with capital S.
I simply hate when someone criticizes Patrick's posts as being just marketing material for his product. Let me tell you this. If I had that much dedication for software quality, to the point that I had created a great product to empower everyone, I'd also be trying to explain the problem to you using the tool I wrote. Heck, I'm pretty sure if someone else had written NDepend Patrick would still be writing about these things and using the tool in the process.
I like code metrics and static analysis a lot as well, not nearly as much as Mr Smacchia though. I'm very excited that very soon I'll get to use it in our code base, in our CI server. I can't wait to learn more about this science and inflict positive changes in our code. Like everybody else, we know there's dirt and bad smells in our code and it's just awesome that there's a tool that can help us clearly identify, mitigate, and track it.
My hope is that I'll be able to come back here and share what I've learned about my code and how the process we went through to improve it.
Ok, so it is official I have jumped on the ‘gotta have a mac bandwagon’. The week prior to father’s day my lovely wife decided that I could get a new MacBook Pro (well, Dimecasts was going to pay 75% of the cost and she would pay the other 25%). I decided that I was not going to make this new machine my primary box, so I went small and picked up the 13.3 model.
So, why did I get one? Because I could silly :). No, mostly to learn and play. I want to learn how to code in a different environment and with different languages. On my list is Ruby (of course), Objective-C and maybe some playing with Java. I do plan on building a iPhone app for Dimecasts (just need to find the time now).
With about 2 weeks of using/playing under my belt and I have to admit the transition has been pretty easy. About the only real annoyance is the fact that they keyboard is a bit different than a PC, but over time.
Anyway, thought I would share with the world that I got a new toy. BTW, Windows 7 runs SUPER fast under VM on this box.
We’ve been getting many requests on having fluent configuration for NHibernate Integration Facility, and as I like programmatic configuration more than XML configuration (did I mention that I hate XML?), I decided to work on it. After 2-3 hours, I got the below more or less working
container.Register(Fluently.ConfigureFacility() .Id("nhibernateFacility") .DefaultConfigurationBuilder<DefaultConfigurationBuilder>() .DefaultConfigurationPersister<DefaultConfigurationPersister>() .AddFactory( Fluently.ConfigureFactory() .Alias("myAlias") .Id("myId") .UsingConfiguration( FactoryConfigurator.DefaultBuilder() .ConnectionProvider("…………………………") .ConnectionDriver("…………………………") .ConnectionString("…………………………") .Dialect("…………………………") .ProxyFactory("…………………………") .Assemblies("…………………………"))) .AddFactory( Fluently.ConfigureFactory() .Alias("myAlias") .Id("myId") .UsingConfiguration( FactoryConfigurator.XmlBuilder().File("myFile.xml"))));
The pieces in Italic are not necessary to write as they have their defaults, also we have some generic overloads for things like Dialect, ProxyFactory and ConnectionProvider.
What the above interface does is that it actually converts all the above configuration to IConfiguration and add them to the container as Facility Configuration, this is actually what is done behind the scenes when you use XML configuration.
I asked for a review over the syntax from several tweeps (@kkozmic, @dagda1, @mikehadlow, @chriscanal) and from one other NH Facility user, German Schuager, and got great feedback.
One of the issues that they pointed out with the above interface is that it is less discoverable. You have to find Fluently class, and then FactoryConfigurator class. Another issue is that it feels less natural to configure the facility like this. Instead, they prefer the configuration take place right on the facility.
This one is what German Schuager has suggested
container.AddFacility<NHibernateFacility>("nhibernateFacility", cfg => cfg .DefaultConfigurationBuilder<DefaultConfigurationBuilder>() .DefaultConfigurationPersister<DefaultConfigurationPersister>() .AddFactory("id1", f => f .Alias("myAlias") .UsingConfiguration<DefaultBuilder>(c => c .ConnectionProvider("………") .ConnectionDriver("………") .ConnectionString("………") .Dialect("………") .ProxyFactory("………") .Assemblies("………") )) .AddFactory("id2", f => f .Alias("alias") .UsingConfiguration<XmlBuilder>(c => c .ReadFrom("myfile.xml") )) });
and similar one from Krzysztof Kozmic.
Looks like i was the only one that is fan of Castle Microkernel style Fluent Interface.
Let’s see what I’ll come up for the second take, If I ever do it.
I like VAN meetings, and I believe I am gaining a lot from them. Due to some time zone problem, I remember waiting 1 hour in front of the PC :) I had even plans for presenting something on those VANs but nah things don’t go like the way I want. Zachariah Young informed me that there are 2 VANs in the following two weeks that cover some topic on Castle. I believe it would be a good idea to join to those meetings, even if you’re using some other framework or don’t use anything at all.
Ryan will be doing a two part series on the Castle Project. Mark your calendar for some Castle Project fun.
A little information on Ryan Svihla Ryan Svihla has been working as a C# developer Farm Bureau Bank in San Antonio since September 2007. Before that he worked as a Consultant in Lincoln, NE for 3 years, where he had working experience with Php, some Perl, Python and of course C#. Attemping Agile since early 2008 as an eager student with a focus on making programming more useful and relevant for the end user.
IoC and Dip through Castle Windsor I assume readers have some familiarity with IoC and DI, so I skip description Central Daylight Time Start Time: Web, July 1, 2009 8:00 PM UTC/GMT -5 hours End Time: Web, July 1, 2009 10:00 PM UTC/GMT -5 hours Attendee URL: http://snipr.com/virtualaltnet (Live Meeting)
Web Development with Castle Monorail, Active Record and Brail view engine Have a look at the first popular MVC .Net based web framework. Also will be covering persistance with ActiveRecord, and view templates using Brail. Bonus, will demo a plugin framework for building CMS like applications. Central Daylight Time Start Time: Web, July 8, 2009 8:00 PM UTC/GMT -5 hours End Time: Web, July 8, 2009 10:00 PM UTC/GMT -5 hours Attendee URL: http://snipr.com/virtualaltnet (Live Meeting)
For more info on VAN go to www.virtualaltnet.com
I’ll try to join those, see you there!
I just read Ron Jefferies latest post entitled My Named Cloud is Better Than Your Named Cloud and it got me riled up enough to post something I've been meaning to write about for at least a couple of years. His post touches on the point I'd wanted to make, but doesn't quite say it as simply as I think it can be said. Here's what I'm thinking:
If we could just always be honest with ourselves, as people, team members and organizations, software development wouldn't be that hard.
There. Simple. Think about it for a second. All this stuff that we label and group together under methodologies and processes is really there so that we can do One Thing. This one thing, I'm assuming, is usually to create software that fulfills a need. Let's pretend that a software team has been assembled to create an application that fulfills such a need. They've chosen to use the XP methodology while writing this application. I'll go through some of the tenets of XP and run them through my honesty filter:
Now obviously there is more to XP than what I've listed. The point is that those three things exist to handle a need that most teams, if they are really honest with themselves have:
Listen. We have methodologies and processes for a reason (I hope). Some of these processes may work for you. However, maybe only some parts of a process work for you. The point is, it's not about the process. If you can understand why you're using a particular piece of a process, you can assess whether it's useful for your team. Who cares whether you're doing XP, Scrum, Lean, Kanban, Waterfall, or Hack 'n' Slash. Those are just names. Identify your pain points, problems, worries, etc, and try to fix them. Honestly.
From the beginning of my current project we have been working under some horrible constraints, many imposed by legacy systems, many by late decisions that would have speeded things immensely if made earlier, and many imposed by decisions that are outside of my control.
This lead us early on to make decisions on architecture that eliminated any possibility of using DDD heavily, and as I mentioned in my original post about this project it is also essentially a glorified CRUD system - we read data from databases, we modify it a bit, and we put it back again.
The first architectural choice that I made, and in hindsight got accepted with relative ease, was to employ CQS to simplify the system.
Earlier projects had suffered quite badly from being abstractions of legacy systems with new functionality bolted on. As
far as possible I wanted to eliminate this problem from our project, as I was all too aware that this was an easy trap for the team to fall into, and would burn a lot of development time very fast.
To make the system simpler I chose to separate our query mechanisms from the "domain" type stuff, our commands and data writing/updating code.
CQS is a pretty simple concept. One path through your system is responsible for querying of anything much more than "Get By ID" type calls. This side of our system is responsible for reading data from legacy systems, reading data from legacy web services, and for reading data from our application database.
The Query side deals largely in DataTables, DataSets and a very very limited number of DTOs. This data is largely and essentially used for display purposes, it is the contents of search results, the results of postcode lookups, the information to populate dropdown lists and tables.
The Query side of CQS does not need strongly typed entities, nor does it require strongly typed DTOs - as it is largely ad-hoc data maintaining these entities and DTOs would consume a disproportionate amount of development time for something a DataTable can deal with more than adequately.
Our Query side actually uses the Query Object pattern, most of which encapsulate a call to an Oracle DB, some of which wrap simple NHibernate criteria and a few of which sit around web services. These are fronted by a WCF facade, which allows us to put these queries out of process, and to cache them aggressively should be need.
What we do not have in the system anywhere, and especially in the Query side, is any big entity model – we have two very small entity models (5 entities in total) used for very specific functions within our application.
The Command side of the CQS equation is a little different. Firstly, it deals with anything that is essentially a request to "go do something". In our case these are commands like "SaveDraft" and "CancelPolicy"
The Command side can write data to the databases, the Query side is not allowed to.
If we were doing DDD, this is where our Domain would sit - and in fact we have been referring to this as "the domain" for most of this project. But, we aren’t using DDD and we don't really have a Domain Model. It is however where most stuff we could describe as "logic" lives. This is primarily a bunch of application services, most of which operate in response to messages fired over MSMQ using NServiceBus.
This side of the architecture has a number of listeners that are responsible for pulling messages from various MSMQs and for dealing with the specific requests, for example pushing data back to our legacy systems, for logging, and eventually for notifications.
Early on, the use of CQS paid for itself easily. By removing the complications of maintaining read and write models together, we quickly managed to get working prototype up and running, with no need for a "domain" or entity model up front.
As the project has progressed, this decision has helped simplify decisions that otherwise would have involved structural or fundamental changes to the architecture – but more importantly, it has helped all of the developers think in terms of a command driven system, rather than viewing the system as CRUD over a database.
We’ve just started a new Silverlight project and since our the UI guy is not on site with us, I ended up with the task of producing screen mockups. Some interest was expressed in using Balsamiq Mockups, and this seemed like a good time to really take it for a test drive.
Balsamiq is a tool for quickly authoring mockups of applications and websites. My favorite tool for doing mockups is pencil and paper (turns out that it’s really, really good). However, we needed something that we could readily show during a review meeting and my sketches don’t photocopy well.
Nevertheless, I did my brainstorming on paper and I used it for my first round of reviews with the team. This left me with about a dozen pages storyboarding the core of our application.
After the first review, I began recreate it with Balsamiq.
In Balsamiq you start with a blank, gridded canvas and drag various UI elements from a library onto the canvas. It reminds me of Visio a bit, but without so much pain. All of the elements are styled to look like hand-drawn. This is important because it prevents anyone from assuming that the application is “done” when you’re just presenting mockups.
The elements in Balsamiq are impressively intelligent. Most elements allow you to type in some content and they react intuitively to that content. I was amazed a couple of time at how smartly they responded. Balsamiq ships with about 75 elements in its library and there are more being posted all the time. You cannot really extend the library yourself however, though you can incorporate your own images.
Each mockup screen is a single file. They are XML so it’s source control friendly. If you are mocking up an entire application (like I was) you can link the files together. Many of the elements have a link property that you can point to any other Balsamiq files in the same directory. Once you’ve linked up some files, you can “run” your mockups in presentation mode. This allows you to navigate around the application and toggle annotations (like the sticky note in my screen shot). The presentation mode is really cool.
I think that mocking up the UI is a very useful exercise. It helps to expose the behavior of the application that you are going to build and surfaces many insights into what it really needs to do. I still prefer to use paper and pencil for the initial pass. However, I found that following this up with Balsamiq forced me to think through the entire flow of my appplication. My paper storyboards had holes in them that I did not realize until I attempted to express them in Balsamiq.
The reviewers were really excited to see the Balsamiq mockups and being able to walk them through the application was a definite plus for them. The tool is easy to use. I would say that any designer developer doing UI work should be using a tool like Balsamiq.
What it offers for $79 is really hard to beat. Admittedly, I don’t know what other tools are out there and how they compare. By itself, I think it definitely worth it for anyone doing UI work.
Of course, there is SketchFlow. It is coming. I think that SketchFlow looks very promising, especially for us XAML guys, but it’s not available yet. I’ll let you know what I think about the overlap once I get a change to actually use SketchFlow.
I had a couple of annoyances that are worth pointing out.
First, you cannot create reusable components. For example, I had certain elements of the application that appeared in several places. I had to clone these elements, but when I needed to change them, I had to make the change in each element. (Another reason to start with pencil).
I think that it would also be nice if there was a “back button” in presentation mode. Within my mockup I had a few screens that you could get too in multiple ways, however I did not have an easy way of returning the the previous screen.
I also get the impression that the community around Balsamiq likes to poke fun at us PC guys. I smile politely.
Finally, Balsamiq likes to keep all of the linked files open. You’ll notice an excessive number of tabs on the bottom of the screen shot. Those are all the screens within the application I was mocking. It became a little difficult to find that right one.
On the whole, Balsamiq is a smart application and I expect to see great things as it matures. Many of its features are intuitive and “just work”, and that’s how I like my software to roll.
:-P
UPDATE 2: Now solution folders and some other stuff are done, thanks to Huseyin Tufekcilerli
UPDATE: I updated the dlls and the source in the link, now it doesn't crash VS. Hopefully the only problem left is that solutions with multiple solution folders won't be reflected in Projects tab.
I have spent a couple of days on implementing a fast add reference dialog box for Visual Studio (with some help from an existing addin). The time of adding a reference has been a great time to have some coffee, to have lunch, or even a way to save economy (remember, developer time costs money!). If you don’t believe me, take a look at what tweeps say.
It is actually easy once you find some of the extension points of Visual Studio.
In my case, I had to implement IDTExtensibility2 which contains method signatures to be called when a plugin is loaded, unloaded etc.
As first step, I had added “Add Quick Reference” item to the context menu when a project is right clicked. This is the most tricky part as there is almost no documentation on that.
The method that we should implement for this is:
public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
The type of the application parameter implements DTE2 interface and the addInInst parameter implements AddIn interface, which has all we need.
The DTE2 interface has CommandBars property which gives us access to various VS stuff. The matter is to find the right one. After for-looping all CommandBar item, i found that the place I should add my custom item is “Context Menus”->”Project and Solution Context Menus”->”Reference Root”. Man this is hard to locate! Looking forward to MEF in 2010!
applicationObject = (DTE2)application;addInInstance = (AddIn)addInInst;CommandBars cb = applicationObject.CommandBars as CommandBars;CommandBar bar = cb["Context Menus"];CommandBarPopup cbarControl = bar.Controls["Project and Solution Context Menus"] as CommandBarPopup;var commandBarControls = cbarControl.Controls;this.referenceRoots = commandBarControls["Reference Root"] as CommandBarPopup;button = this.referenceRoots.Controls.Add(MsoControlType.msoControlButton, System.Reflection.Missing.Value, System.Reflection.Missing.Value, 1, true) as CommandBarButton;button.Caption = "Add Quick Reference";button.Click += oControl_Click;
There is one thing to be careful about: If you want to handle events of a button, for example, you should hold a reference in your class. Local method variables wouldn’t work. This situation is better told here
Now, I am done. I should now design the dialog itself that looks very similar to the original one. There is another problem: There is no "Windows Explorer Like” control for Windows Forms. There is OpenFileDialog but it is a dialog, not a control. I found the most similar one at GongShell Project which is licensed under GPL.
My current screen looks like the one below:
Very similar, even if I say so myself.
One thing to notice here is that the first tab is browse(.NET in original dialog), second is .net (Browse in original dialog) and third one is Projects. I haven’t written “Recent” part as I don’t want to deal with I/O really.
I believe that Browse window is more frequently used than .NET tab. There can be more improvements on that screen, such as having “common” tab which does the copying of commonly used references to a new project but hey this is a demonstration only ! :)
The items in the .NET tab are loaded in the background, and once it is loaded, it will be cached during the lifetime of the application.
I won’t comment more on the code, go grab it and try it. I wont continue developing this little addin, so you are free to do it on your own. Just drop me an email when you do it, though.
I just warn you: Com stuff is like walking on a mine field, and I am not taking any responsibility in case you loose data.
Download the code and the binaries here and put the binaries into Documents\Visual Studio 2008\Addins folder. Have fun!
If you like the post and the tool, please Kick! and Shout! it below!
In this post we are going to take a look at what might be considered the most basic usage scenario for the contracts library, Pre and Post condition validation.
What is a pre-condition validation? This is when we want to validate the state of the world (parameters or other state holding values) is valid prior to running a method. Pre-condition validation is done by utilizing the Contract.Requires(…) or Contract.Requires<CustomExceptionHere>(…) method.
The code below is what your pre-condition code could look like the code below:
public ReportCard GetDailyReportCard(Int32 employeeId, DateTime dateForReportCard) { Contract.Requires(employeeId > 0); Contract.Requires<ArgumentOutOfRangeException>(dateForReportCard.Date == DateTime.Now.Date); // do something meaning var reportCard = new ReportCard(employeeId); return reportCard; }
The code above shows 2 different ways you can use the contracts libray. The first simply uses the standard .Requires() logic and is meant to ensure that the employeeId is always > 0. The second uses the overload of .Requires<>() and will provide the exception type which should be thrown if a contract is violated. As we have mentioned before, the contracts library uses Code Weaving to do its magic. Lets take a look at how it re-wrote the .Requires() for us on the back end (via reflector).
public ReportCard GetDailyReportCard(int employeeId, DateTime dateForReportCard) { if (__ContractsRuntime.insideContractEvaluation <= 4) { try { __ContractsRuntime.insideContractEvaluation++; __ContractsRuntime.Requires(employeeId > 0, null, "employeeId > 0"); __ContractsRuntime.Requires(dateForReportCard.Date == DateTime.Now.Date, null, "dateForReportCard.Date == DateTime.Now.Date"); } finally { __ContractsRuntime.insideContractEvaluation--; } } return new ReportCard(employeeId); }
As you can see the code has changed, but not too much.
Now that we have mastered pre-conditions it is time to take a look at post-conditions
What is a post-condition validation? This is when you want to validate the state of a method when that method terminates. With post conditions you can assert that the return value so the caller can be assured the values will always be within range when returned. Post-Condition checks can be done with the Contract.Ensures() method and can take a special command which is Contract.Result<> which allows you to specify the result type and its condition.
The code below is an simple example of how you can create your post-condition check.
public ReportCard GetWeeklyReportCard( Int32 employeeId ) { Contract.Ensures( Contract.Result<ReportCard>() != null ); var reportCard = new ReportCard( employeeId ); return reportCard; }
In the check above we are simply trying to ensure that the return value from this method will never be null. Of course this is just a simple example and you could validate over types of items as well.
As we did in the pre-condition, lets take a look at the code as it exists after code weaving:
public ReportCard GetWeeklyReportCard(int employeeId) { ReportCard reportCard = new ReportCard(employeeId); ReportCard CS$1$0000 = reportCard; ReportCard Contract.Result() = CS$1$0000; if (__ContractsRuntime.insideContractEvaluation <= 4) { try { __ContractsRuntime.insideContractEvaluation++; __ContractsRuntime.Ensures(Contract.Result() != null, null, "Contract.Result() != null"); } finally { __ContractsRuntime.insideContractEvaluation--; } } return Contract.Result(); }
Again you can see that the weaver did its magic, but this time it did a bit more work. The good news for us is that the code still works as intended so there is nothing too much to worry about.
Now that we have taking a look at both pre-conditions and post-condition checking with the contracts library you are more than on your way to utilizing this library in your code.
This Wednesday, June 17th, the Chicago .NET Users Group, CNUG, has invited me to bring my JavaScript presentation to their monthly meeting.
Despite of what the event description might lead you to believe, the talk is hardcore JavaScript, not much specific to Ajax at all, although I believe the material will greatly help you with the Ajax work as well.
You can read the complete talk description and register for the event. Hope to see you there.
About The CodeBetter.Com Blog NetworkCodeBetter.Com FAQOur Mission Advertisers should contact Brendan
Subscribe Google Reader or Homepagedel.icio.us CodeBetter.com Latest ItemsAdd to My Yahoo!Subscribe with BloglinesSubscribe in NewsGator OnlineSubscribe with myFeedsterAdd to My AOLFurl CodeBetter.com Latest ItemsSubscribe in Rojo
Member ProjectsDimeCasts.Net - Derik Whittaker
Friends of Devlicio.usRed-Gate Tools For SQL and .NETNDependSlickEdit SmartInspect .NET Logging NGEDIT: ViEmu and Codekana LiteAccounting.Com DevExpressFixxNHibernate ProfilerUnfuddle Balsamiq MockupsScrumyJetBrains - ReSharper <-- NEW Friend!
Site Copyright © 2007 CodeBetter.Com Content Copyright Individual Bloggers