This time, Joe Developer is building a web application for the company intranet. Most of the site is available to anonymous users, but one directory - the adminPages directory, should only be accessible to users in the machine's local administrators group. Joe added the following to the bottom of his web.config, and is feeling pretty secure.
Should Joe be worried?
I imagine the MS legal department frowns on the appearance of recognizable names in documentation. Nevertheless, there are a few out there. For instance, the documentation for IXmlSerializable.WriteXml contains a celebrity from Bedrock:
Over in the Visual FoxPro world, we find a local Microsoft celebrity:
Finally, perhaps someone had a particular GeorgeW in mind when describing sp_denylogin to aspiring DBAs:
If only it were that easy…
So, know of any others?
Q: Great article on the WWF Rules engine. I am curious how one would implement a rule that is applied to a collection of items, something akin to "IF request.Payments[n].Amount > 10000 THEN request.Payments[n].RequiresApproval = true"
A: There are quite a few approaches to choose from. As usual - it depends on the application!
One solution is to use a WhileActivity and loop through the collection. This explicit approach would run a PolicyActivity for each item in the collection.
The Windows SDK contains an interesting alternative approach in the "Processing Collections in Rules" entry. This is approach is worthy of note because it uses the features and flexibility of the rules engine to perform the iteration without any outside help. The approach specifically relies on the following features:
With a Payment class defined in your domain model, the workflow class can accept an array of Payment references as a parameter:
Next comes the RuleSet:
Name | Priority | Rule |
GetEnumerator | 3 | IF 1=1 THEN this._enumerator = this._payments.GetEnumerator() |
MoveEnumerator | 2 | IF this._enumerator.MoveNext() THEN this._currentPayment = (Payment)this._enumerator.Current |
One Or More Biz Rules | 1 | this._currentPayment.Amount > 10000 THEN this._currentPayment.RequiresApproval = True ELSE this._currentPayment.RequiresApproval = False |
Force re-eval | 0 | IF this._currentPayment == this._currentPayment THEN Update("this/_enumerator/") |
GetEnumerator runs first because it has the highest priority. MoveEnumerator runs second - again because of priority. After these two rules finish, _currentPayment will reference the first Payment object in the array. All the "business" rules could now execute on that payment and decide on an outcome.
The interesting piece happens in the last rule, which always evaluates to true and performs an explicit "Update" on the _enumerator field. "Update" is a rule action that explicitly tells the engine about a side effect. In this rule, we are telling the engine that we've changed _enumerator. Even though we haven't actually changed _enumerator, we've forced the engine to look for previous rules with a dependency on _enumerator.
The rules engine knows the MoveEnumerator rule has a dependency on _enumerator, so it re-executes this rule. If MoveNext returns true in this rule, we update the _currentPayment field. The rules engine also detects this implicit side effect, and will reevaluate all the business rules that depend on _currentPayment. If MoveNext returns false, there are no more side effects and the Policy activity can close.
This is a clever pattern which keeps collection processing inside of a single activity.
The Team Build service in Team Foundation Server includes the current date in the build number by default. To me, the string looks like the random gibberish of a disk head crash.
FooBarBuild_20060928.1
FooBarBuild_20060928.2
…
I know some people are fond of including the date in a build label, but it's a turn off for me. Build labels have a tendency to show up in many places, and a friendly number is easier on the eyes.
FooBar_2.5.1
FooBar_2.5.2
…
FooBar_2.5.176
Fortunately, it's easier to change Team Build with a custom MSBuild task. There are some examples of how to do this out there, but none that generate a truly friendly name. Ideally, the task will start with a base name like "FooBar_2.5" and just generate an extra identity digit. One of the properties in play during a team build is LastBuildNumber, which we can inspect during the task and use to generate the build number we want. The code would look something like this:
Then, register the task in TFSBuild.proj file. I like to deploy the assembly into the MSBuild extensions path to use from multiple projects.
Finally, in the same .proj file, override the build number target to spit a new build label into the system.
TFS is making the CM job easy…
I get the occasional earful from people who are upset with Microsoft. These rants might come electronically, or they might come in person. If I know anything about the particular problem the person is having, I might try to give them some perspective or background on why Microsoft made the software do whatever it is that is causing the person great pain and suffering. I might know a workaround, or I might not. I might make them happier, or I might not. I do try. C'est la vie.
Today, I am on the other side of the fence.
I updated ActiveSync from 3.something to 4.2 today, only to find they removed the ability to synch a device over the network.
Let me express my feelings about this decision by saying - it sucks. It sucks really large, rotten, ostrich eggs.
Joe Developer is working on a new application for a book publisher. Authors can publish zero or more books. Books can have zero or more authors.
Joe wrote a query to get a total count of all authors, and a total count of all books. Joe read on the Internet that the DISTINCT keyword is good to use in these scenarios.
The problem is - the numbers seem too high. What's wrong? Is it easy to fix?
A new article on OdeToCode: State Machines In Windows Workflow. State machines have been a powerful abstraction in software for many years. Using a state machine in Windows Workflow means we get all the tracking, persistence, and meta-data support the workflow runtume offers, which is quite a bonus.