This is a business rule example app.
The guy decided to use double entry bookeeping as a sample app.
Random outpourings of a software developer
This is a business rule example app.
The guy decided to use double entry bookeeping as a sample app.
Once you get your head around ruby constructs the following was easy to write:
As a benefit it actually displays properly…
require ‘socket’
def latest3podcasts(session, podcast)
session.print “
rn”
end
port = 8080.to_i
server = TCPServer.new(‘serveraddress’,port)
while (session = server.accept)
puts “Request: #{session.gets}”
session.print “HTTP/1.1 200/OKrnContent-type: text/htmlrnrn”
session.print “”
latest3podcasts(session, “/storage/podcast/dotnetrocks/*.mp3”)
latest3podcasts(session, “/storage/podcast/hanselminutes/*.mp3”)
latest3podcasts(session, “/storage/podcast/polymorphicpodcast/*.mp3”)
session.print “rn”
session.close
end
A non-technical friend of mine asked me to help her with a problem with her Talk Talk broadband.
Due to various confusions at the Talk Talk end she had three of their modems available.
I went through all of the usual drills involved in setting up the modem. I reentered the username and password, I looked at the connection details and even ran the diagnostics utility (it reported an authentication problem). The computer could access the modem, the modem could read the adsl status, but it would go no further. There were no external connections being made.
The next step was to call the helpdesk. The first try consisted of waiting against piped music and was then disconnected.
The second call got me through to a helpdesk operator who went through her script (ingnoring the fact that I had diagnostic information that should have been of use). The script forces the use of IE under Windows 2000. After 20 mins I was told I was being passed to 2nd line support. The line then disconnected.
The third call got through to another individual who insisted on going through the entire script again. He did not notice that I was able to predict the next step. 20 mins later (including a pointless reboot of a slow laptop) I was eventually passed to second line support. Answering exactly the same questions about the lights on the modem to this individual he determined that the modem was broken (it was clearly accessing the ADSL line, but he ignored that). I am now awaiting the arrival of the new modem so I can go and set it up again.
Over the last year I have been working on a couple of applications (Winforms) that use the MVP pattern. There is a lot of articles published covering MVC and MVP to various degrees of detail. They all seem to stop at the point where you have one controller, one view and a simple model. I am trying to find out if anyone else has been trying to solve the same problem in the same way. Very little of the literature actually describes the implementation of a Domain Model.
The model component consists of a Domain Model that is a tree of Composite Entities with attached Business Rules. The Business Rules entities use XPathNavigator to negotiate the structure of the model. We have defined an abstract type system for the attributes so that that can be treated polymorphically (all types may be set to a string) and may be invalid (for example an integer attribute may be set to “XXX”). Our business rules perform a selection of functions: Providing defaults, performing calculations and providing validation. When the rules are applied we obtain a set of rule messages that determines the result of the action. Business functions are implemented as Facades over the model components so that the controller need only make a single call. By using our navigator compenents we can refer to other parts of the model using an XPath expression – this makes our rules rugged with respect to changes in the structure of the model (for excample introduction of an intemediate node).
The Business Entity layer is distinct from the persistance layer – it only depends upon the database to provide the values of the primary keys which it holds as attributes. The Pesistence Layer consists of a set of interfaces that may be implemented by a concrete implementation. By keeping the persistance layer distinct from the model we protect ourselves from changes in the persistance mechanism. Our reporting requirements have forced us to duplicate calculations between views and the rules. Since we load the model from the views it is an easy task to ensure that these calculations are in step (we have a model checker that loads each business entity from the database and fires the rules – if the model and database views are in step then there will be no mesages recorded).
The closest that I have found to what we are doing is the CSLA.NET. The big difference is that CSLA deals in terms of a collection of “broken rules” and unifies the persistance and data access objects. It seems to provide no core functionality for implementing business functions other than validation and authorisation.
The Microsoft UIP seems to implement the Model View Controller pattern. This is a very heavyweight solution and seems to have reduced the model component to little more than a data container.
The Microsoft Validation Application block seems to be heading in the same direction as the business rules approach that we have been taking. Again this stops at validation (no defaults or calculations) and may only validate a single object.
Simian is a relatively cheap code analysis tool. It performs simularity analysis on a whole range of files. It is great for detecting cut and paste code that really needs to be refactored. It costs $450 per project for commercial use. I am unsure of how the costs scale up for the enterprise version.
I found this as one of the cruise control options.
A recent dotnet rocks defined Cruise Control.NET as:
10 Get and build all files under version control if any file has changed
20 GOTO 10
It is a little more powerful than that. It is a generalised scheduling program that can run tasks on a timed schedule or once a polled event occours. I am sure that a number of major end-user applications could be built around this (scheduled reports, model integrity checks).
I now have two of the four C# projects at my work built under cruise control.
I am using PVCS which does not integrate very cleanly as it’s pcli tool is frankly a little cranky.
I have managed to put together a batch file that pulls all of the files from a project with a given promotion group. This gets called as a prebuild task. I then use the msbuild task to build the project and the nunit task to test the project. The build script is set to run three times per day: just before I start for the day, at lunchtime and just after I leave. This is not quite the intended instant feedback but is a hell of a lot better than finding the build is broken when you are just about to apply an important critical fix.
The web application that can be used to monitor CC is very good. It allows drill down to the times that individual tests took to run! It also permits a build to be run on demand.
The only problem I have at the moment is that the CC.net website is down so I can’t get the source…
This is a set of articles on use of version control software.
He does work for the company that makes Vault.
Boo is great for lightweight experiments:
=== myclass.boo ===
namespace foo
class myclass:
def foo():
print(“Hello”)
c = myclass()
c.foo()
===============
=== myclass2.boo ===
import foo from “myclass.exe”
c = myclass()
c.foo()
=================
Create the two above files.
Compile both with the booc compiler.
run myclass2.exe
This shows how easy it is to extend a .net app in Boo.
# Podcatcher.boo
#
# (C) Chris Eyre 2007
# This is released under the BSD licence.
#
# This is the start of a podcast download script.
# I have been unable to find a suitable podcast client to replace iPodder under Ubuntu 7.4
# so there was a need to write one.
#
# Required features:
# Download a podcast to a defined directory.
# Easy reload.
# No excessive configuration.
#
# Todo:
# Scheduler
# UI
# bitorrent support.
# Currently it is portable between Mono and .Net
import System.IO
import System.Net
import System.Xml
# This reads a file structured:
# podcastlist
# podcast
# name
# url
# output
#
def ProcessFeeds(target as string):
x = XmlDocument();
x.Load(target)
for xnode as XmlNode in x.FirstChild.ChildNodes:
url = xnode.SelectSingleNode(“url”).InnerText
name = xnode.SelectSingleNode(“output”).InnerText
ProcessFeed( url, name)
#Decodes the RSS feed.
def ProcessFeed(uri as string, output as string):
w = WebClient()
x = XmlDocument()
x.Load(w.OpenRead(uri))
xnode = x.SelectSingleNode(“//channel”)
for itemnode as XmlNode in xnode.ChildNodes:
if itemnode.Name == “item”:
url = itemnode.SelectSingleNode(“enclosure/@url”).InnerText
print(url)
GetPodcast(url, output)
// Grabs the podcast if not already got.
// If the downloaded file is corrupt then delete it and it will be replaced on the next run.
def GetPodcast(podcast as string, output as string):
filename = output + “/” + NameFromUrl(podcast)
if not File.Exists(filename):
WebClient().DownloadFile(FixUrl(podcast), filename)
# another hack for .NetRocks
def FixUrl(url as string) as string:
if Path.GetExtension(url) == “.torrent”:
return Path.ChangeExtension(url,null)
else:
return url
def NameFromUrl(url as string) as string:
#HACK: This may work for dotnet rocks, but I am still working on a torrent client
if Path.GetExtension(url) == “.torrent”:
return Path.ChangeExtension(Path.GetFileName(url),null)
else:
return Path.GetFileName(url)
ProcessFeeds(“/home/chris/Projects/PodCatcher/list.xml”)
print(“done”)