F# is a relatively new .NET technology that is worthy of a developer’s arsenal. It provides quite a few benefits such as type inference, native non-mutable states for concurrency, pattern matching and script-esque capabilities.
One thing I would love is the ability to write unit tests in F#. I believe the resulting code would be succinct and reusable. Though, I have not figured out such a framework, here is my first attempt at F# through the famous Black Scholes .
Without much of a history, finance or math lesson, Black Scholes is an equation to price options. Basically, an option is a financial instrument that gives the buyer the option to buy or sell another underlying asset at a certain price in the future for a premium paid today. Black Scholes is a closed form equation to help estimate the premium to charge for such an option. #light
open System
type PutOrCall =
| Call = 1
| Put = 2
let CumulativeNormalDistribution (x: double) =
let L = abs(x)
let K = 1.0 / (1.0 + 0.2316419 * L)
let dcnd =
1.0
- 1.0
/ sqrt(2.0 * Math.PI)
* exp(-L * L / 2.0)
* (0.31938153 * K
+ -0.356563782 * K * K
+ 1.781477937 * Math.Pow(K, 3.0)
+ -1.821255978 * Math.Pow(K, 4.0)
+ 1.330274429 * Math.Pow(K, 5.0))
if x < 0.0 then 1.0 - dcnd
else dcnd
let BlackScholes (pc: PutOrCall) stock strike time interestRate vol =
let d1 = (log(stock / strike)
+ (interestRate + vol * vol / 2.0) * time)
/ (vol * sqrt(time))
let d2 = d1 - vol * sqrt(time)
if pc = PutOrCall.Call then
stock * CumulativeNormalDistribution(d1) -
strike * exp(-interestRate * time) * CumulativeNormalDistribution(d2)
else
strike * exp(-interestRate * time) * CumulativeNormalDistribution(-d2) -
stock * CumulativeNormalDistribution(-d1)
I finally decided to get a new laptop to support at my home development process. My previous laptop was a three year old IBM Think Pad. Unfortunately, trying to run Visual Studio 2008 (with many of the new additions) and Office 2007 was painfully slow. Basically, I found myself waiting 5-10 minutes between builds on large scale projects.
While researching which laptop to get, the hardware was the easy part. My dream choice was an Intel Core 2 Duo, 4 GB Ram and 200 GB @ 7200 rpm. The much harder question was which brand: IBM, Dell, Sony or another computer. After quite a bit of research, I decided why not a MAC?
One might think; how does one run Visual Studio on a Mac? Vmware fusion is the answer. If you have never tried developing on a virtual machine, it is must. Moreover, when you can run Windows Server 2008 and Vista Ultimate simultaneously to replicate a SOA environment is amazing. Furthermore, debugging the SOA environment is a breeze with the .NET remote debugger.
Another benefit of virtual machines is the ability to save states. The obvious reason is recovery; however, two other reasons are more useful in daily development. First, the ability to suspend a development session and restart, at a later time, exactly where you left off. Furthermore, the restarting of session seems faster than restarting the operating system and visual studio. Second, the ability pass a session to a fellow developer is quite useful. Basically, this saves quite a bit of time explaining setup procedures to another developer.
Finally, I choose Vmware over Parallels mainly because of the dual core support. The Unity view allows me to seamlessly browse the web in safari and program in visual studio. Though I don’t do much website design, I could imagine such a scenario could be quite useful.
All in all, I am very happy with my current enviorment.
Due to the fact my background is in financial markets (trading systems to be exact), I find my self continuously trying to scrounge up milliseconds by code improvements. My weapon of choice is parallel processing or otherwise called threading. Over the years it has been both my greatest asset any my most malevolent foe. Many have commented on the impeding doom of mutable states and many core processors in software design; hence functional programming.
I have aspiration to neither speak about functional programming nor give a class on threading best practices. Instead, I am interested in providing an easier ReaderWriterLock schematic; most likely to the joy of my team.
The “lock{}” keyword (or “SyncLock” keyword for VB.NET) is very useful and concise in its usage; though anyone trying to squeeze milliseconds knows the performance benefits of a ReaderWriterLock in many cases. (Stop here if the previous statement doesn’t make sense to you and go Google the ReaderWriterLock.) However, the implementation of a ReaderWriterLock requires much more code and can cause dead locks if implemented incorrectly.
Thus, I came up with the attached solution. It offers improvements on two fronts. One, it allows a user to retry a function N number of times before raising an exception. Second, it ensures the locks are acquired and released correctly.
I am not exactly thrilled with this design because the use of anonymous methods makes for a non simple solution. Nevertheless, I think it is better then writing the internalized code in ever method that needs to be locked. Finally, I have not performance tested this yet; but I will post later with results. public class ClassThanNeedsLocking
{
ReTryReaderWriterLock _rw = new ReTryReaderWriterLock();
private Dictionary<double, double> _valueMap;
public ClassThanNeedsLocking()
{
this._valueMap = new Dictionary<double, double>();
}
public void AddSomething(double key, double value)
{
ReTryReaderWriterLock.FunctionalityToLock temp = delegate
{
this._valueMap.Add(key, value);
};
this._rw.WriterLockFunction(temp, 100, 5, 10);
}
public double GetSomething(double key)
{
double value = 0;
ReTryReaderWriterLock.FunctionalityToLock temp = delegate
{
if (this._valueMap.TryGetValue(key, out value))
{
throw new ArgumentException("Key Does Not Exist.", "key");
}
};
this._rw.ReaderLockFunction(temp, 100, 5, 10);
return value;
}
}
public class ReTryReaderWriterLock
{
public delegate void FunctionalityToLock();
private delegate void RepeatTryLock(int timesTried);
private ReaderWriterLock _rw = new ReaderWriterLock();
private ILock _reader = new ReaderLock();
private ILock _writer = new WriterLock();
public void ReaderLockFunction(FunctionalityToLock function, int timeOutPerTry, int timesToTry, int timeToWaitBeforeTryingAgain)
{
LockFunction(function, timeOutPerTry, timesToTry, timeToWaitBeforeTryingAgain, this._reader);
}
public void WriterLockFunction(FunctionalityToLock function, int timeOutPerTry, int timesToTry, int timeToWaitBeforeTryingAgain)
{
LockFunction(function, timeOutPerTry, timesToTry, timeToWaitBeforeTryingAgain, this._writer);
}
private void LockFunction(FunctionalityToLock function, int timeOutPerTry, int timesToTry, int timeToWaitBeforeTryingAgain, ILock typeOfLock)
{
RepeatTryLock repeater = null;
repeater = delegate(int timesTried)
{
try
{
typeOfLock.Acquire(this._rw, timeOutPerTry);
function();
}
catch (ApplicationException)
{
if (timesTried < timesToTry)
{
Thread.Sleep(timeToWaitBeforeTryingAgain);
timesTried += 1;
repeater(timesTried);
return;
}
throw;
}
finally
{
typeOfLock.Release(this._rw);
}
};
repeater(0);
}
private interface ILock
{
void Acquire(ReaderWriterLock rw, int timeOutPerTry);
void Release(ReaderWriterLock rw);
}
private class ReaderLock : ILock
{
public void Acquire(ReaderWriterLock rw, int timeOutPerTry)
{
rw.AcquireReaderLock(timeOutPerTry);
}
public void Release(ReaderWriterLock rw)
{
if (rw.IsReaderLockHeld == true)
{
rw.ReleaseReaderLock();
}
}
}
private class WriterLock : ILock
{
public void Acquire(ReaderWriterLock rw, int timeOutPerTry)
{
rw.AcquireWriterLock(timeOutPerTry);
}
public void Release(ReaderWriterLock rw)
{
if (rw.IsWriterLockHeld == true)
{
rw.ReleaseWriterLock();
}
}
}
}
I am sure I have said this before; has anyone else noticed how little code I have written? I have quite a bit to talk about, so tonight I will just drop all my code and screen shots unaccompanied. Thereafter, we will spend the next few evening talking about exactly what was done.
First, I created the data contracts.

Second, I created the service contracts.

Third, I added a Silverlight browser project.

Fourth, I added the WPF XAML for the Silverlight front end.
<UserControl x:Class="DBinsor.Svc.WCF.Browser.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:grid ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data">
<Grid x:Name="LayoutRoot" Background="White" ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="90" />
<RowDefinition Height="50*" />
<RowDefinition Height="50*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>
<grid:DataGrid x:Name="CastleGrid" AlternatingRowBackground="Beige"
AutoGenerateColumns="True" Grid.Row="1" Grid.Column="2"
MouseLeftButtonDown="CastleGrid_MouseLeftButtonDown" />
<grid:DataGrid x:Name="ContractGrid" AlternatingRowBackground="Beige"
AutoGenerateColumns="True" Grid.Row="1" Grid.Column="1"
MouseLeftButtonDown="ContractGrid_MouseLeftButtonDown"/>
<grid:DataGrid x:Name="ComponentGrid" AlternatingRowBackground="Beige"
AutoGenerateColumns="True" Grid.Row="2" Grid.Column="2"
MouseLeftButtonDown="ComponentGrid_MouseLeftButtonDown" />
<grid:DataGrid x:Name="ImplementationGrid" AlternatingRowBackground="Beige"
AutoGenerateColumns="True" Grid.Row="2" Grid.Column="1" />
<grid:DataGrid x:Name="ComponentParametersGrid" AlternatingRowBackground="Beige"
AutoGenerateColumns="True" Grid.Row="3" Grid.Column="2"
CanUserResizeColumns="True" />
<grid:DataGrid x:Name="ContractParametersGrid" AlternatingRowBackground="Beige"
AutoGenerateColumns="True" Grid.Row="3" Grid.Column="1"
CanUserResizeColumns="True" />
</Grid>
</UserControl>
Fifth, I hooked the WCF Service to the Silverlight browser.
using System;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Input;
using DBinsor.Svc.WCF.Browser.DatabaseProxy;
namespace DBinsor.Svc.WCF.Browser
{
public partial class Page : UserControl
{
DatabaseServiceContractClient _dscc;
Castle _selectedCastle;
Contract _selectedContract;
Component _selectedComponent;
public Page()
{
InitializeComponent();
this._dscc = new DatabaseServiceContractClient();
this._dscc.DemandCastlesCompleted
+= new EventHandler<DemandCastlesCompletedEventArgs>(_dscc_DemandCastlesCompleted);
this._dscc.DemandComponentParametersCompleted
+= new EventHandler<DemandComponentParametersCompletedEventArgs>(_dscc_DemandComponentParametersCompleted);
this._dscc.DemandComponentsCompleted
+= new EventHandler<DemandComponentsCompletedEventArgs>(_dscc_DemandComponentsCompleted);
this._dscc.DemandContractParametersCompleted
+= new EventHandler<DemandContractParametersCompletedEventArgs>(_dscc_DemandContractParametersCompleted);
this._dscc.DemandContractsCompleted
+= new EventHandler<DemandContractsCompletedEventArgs>(_dscc_DemandContractsCompleted);
this._dscc.DemandImplementationsCompleted
+= new EventHandler<DemandImplementationsCompletedEventArgs>(_dscc_DemandImplementationsCompleted);
LoadPrimaryTables();
}
private void LoadPrimaryTables()
{
this._dscc.DemandCastlesAsync();
this._dscc.DemandContractsAsync();
}
private void _dscc_DemandCastlesCompleted(object sender, DemandCastlesCompletedEventArgs e)
{
if (e.Error != null)
{
HtmlPage.Window.Alert(e.Error.Message);
return;
}
if (e.Result.Count == 0)
{
return;
}
this.CastleGrid.ItemsSource = e.Result;
}
private void _dscc_DemandComponentParametersCompleted(object sender, DemandComponentParametersCompletedEventArgs e)
{
if (e.Error != null)
{
HtmlPage.Window.Alert(e.Error.Message);
return;
}
if (e.Result.Count == 0)
{
return;
}
this.ComponentParametersGrid.ItemsSource = e.Result;
}
private void _dscc_DemandComponentsCompleted(object sender, DemandComponentsCompletedEventArgs e)
{
if (e.Error != null)
{
HtmlPage.Window.Alert(e.Error.Message);
return;
}
if (e.Result.Count == 0)
{
return;
}
this.ComponentGrid.ItemsSource = e.Result;
}
private void _dscc_DemandContractParametersCompleted(object sender, DemandContractParametersCompletedEventArgs e)
{
if (e.Error != null)
{
HtmlPage.Window.Alert(e.Error.Message);
return;
}
if (e.Result.Count == 0)
{
return;
}
this.ContractParametersGrid.ItemsSource = e.Result;
}
private void _dscc_DemandContractsCompleted(object sender, DemandContractsCompletedEventArgs e)
{
if (e.Error != null)
{
HtmlPage.Window.Alert(e.Error.Message);
return;
}
if (e.Result.Count == 0)
{
return;
}
this.ContractGrid.ItemsSource = e.Result;
}
private void _dscc_DemandImplementationsCompleted(object sender, DemandImplementationsCompletedEventArgs e)
{
if (e.Error != null)
{
HtmlPage.Window.Alert(e.Error.Message);
return;
}
if (e.Result.Count == 0)
{
return;
}
this.ImplementationGrid.ItemsSource = e.Result;
}
private void CastleGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
object temp = CastleGrid.SelectedItem;
if (temp == null)
{
return;
}
this._selectedCastle = temp as Castle;
this._dscc.DemandComponentsAsync(this._selectedCastle);
}
private void ContractGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
object temp = ContractGrid.SelectedItem;
if (temp == null)
{
return;
}
this._selectedContract = temp as Contract;
this._dscc.DemandImplementationsAsync(this._selectedContract);
this._dscc.DemandContractParametersAsync(this._selectedContract);
}
private void ComponentGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
object temp = ComponentGrid.SelectedItem;
if (temp == null)
{
return;
}
this._selectedComponent = temp as Component;
this._dscc.DemandComponentParametersAsync(this._selectedComponent);
}
}
}
Sixth, I used LINQ to Extract Data from the Entity Framework.
using System.Linq;
namespace DBinsor.Svc.WCF.BusinessLogic
{
public static class DatabaseToDataContractGenerator
{
public static DataContracts.Castles GetCastles()
{
using (DataAccess.Model.Entities db =
new DataAccess.Model.Entities())
{
DataContracts.Castles ret = new DataContracts.Castles();
var dataCastles = from castle in
db.Castle
select castle;
foreach (DataAccess.Model.Castle dataCastle in dataCastles)
{
DataContracts.Castle serviceCastle =
new DataContracts.Castle();
serviceCastle.id = dataCastle.Id;
serviceCastle.name = dataCastle.Name;
ret.Add(serviceCastle);
}
return ret;
}
}
public static DataContracts.Components GetComponents(DataContracts.Castle castle)
{
using (DataAccess.Model.Entities db =
new DataAccess.Model.Entities())
{
int temp;
DataContracts.Components ret = new DataContracts.Components();
var dataComponents = from component in
db.Components
where component.Castle.Id == castle.id
select component;
foreach (DataAccess.Model.Components dataComponent in dataComponents)
{
DataContracts.Component serviceComponent =
new DataContracts.Component();
serviceComponent.id = dataComponent.Id;
int.TryParse(dataComponent.InitialPoolSize.ToString(), out temp);
serviceComponent.initialPoolSize = temp;
serviceComponent.inspectionBehavior = dataComponent.InspectionBehavior;
serviceComponent.lifestyle = dataComponent.Lifestyle;
int.TryParse(dataComponent.MaxPoolSize.ToString(), out temp);
serviceComponent.maxPoolSize = temp;
serviceComponent.Castle = castle;
serviceComponent.Implementation = new DataContracts.Implementation();
//todo: Add Implementation Name
ret.Add(serviceComponent);
}
return ret;
}
}
public static DataContracts.ComponentParameters GetComponentParameters(DataContracts.Component component)
{
using (DataAccess.Model.Entities db =
new DataAccess.Model.Entities())
{
DataContracts.ComponentParameters ret = new DataContracts.ComponentParameters();
var dataComponentParameters = from componentParameter in
db.ComponentParameters
where componentParameter.Components.Id == component.id
select componentParameter;
foreach (DataAccess.Model.ComponentParameters dataComponentParameter in dataComponentParameters)
{
DataContracts.ComponentParameter serviceComponentParameter =
new DataContracts.ComponentParameter();
serviceComponentParameter.Component = component;
serviceComponentParameter.overrideValue = dataComponentParameter.OverrideValue;
//todo: Add Contract Parameter Name
ret.Add(serviceComponentParameter);
}
return ret;
}
}
public static DataContracts.Contracts GetContracts()
{
using (DataAccess.Model.Entities db =
new DataAccess.Model.Entities())
{
DataContracts.Contracts ret = new DataContracts.Contracts();
var dataContracts = from contract in
db.Contracts
select contract;
foreach (DataAccess.Model.Contracts dataContract in dataContracts)
{
DataContracts.Contract serviceContract =
new DataContracts.Contract();
serviceContract.id = dataContract.Id;
serviceContract.contractNamespace = dataContract.Namespace;
serviceContract.contractInterface = dataContract.Interface;
ret.Add(serviceContract);
}
return ret;
}
}
public static DataContracts.Implementations GetImplementations(DataContracts.Contract contract)
{
using (DataAccess.Model.Entities db =
new DataAccess.Model.Entities())
{
DataContracts.Implementations ret = new DataContracts.Implementations();
var dataImplementations = from implementation in
db.Implementations
where implementation.Contracts.Id == contract.id
select implementation;
foreach (DataAccess.Model.Implementations dataImplementation in dataImplementations)
{
DataContracts.Implementation serviceImplementation =
new DataContracts.Implementation();
serviceImplementation.name = dataImplementation.Name;
serviceImplementation.Contract = contract;
ret.Add(serviceImplementation);
}
return ret;
}
}
public static DataContracts.ContractParameters GetContractParameters(DataContracts.Contract contract)
{
using (DataAccess.Model.Entities db =
new DataAccess.Model.Entities())
{
DataContracts.ContractParameters ret = new DataContracts.ContractParameters();
var dataContractParameters = from contractParameter in
db.ContractParameters
where contractParameter.Contracts.Id == contract.id
select contractParameter;
foreach (DataAccess.Model.ContractParameters dataContractParameter in dataContractParameters)
{
DataContracts.ContractParameter serviceContractParameter =
new DataContracts.ContractParameter();
serviceContractParameter.name = dataContractParameter.Name;
serviceContractParameter.defaultValue = dataContractParameter.DefaultValue;
serviceContractParameter.Contract = contract;
ret.Add(serviceContractParameter);
}
return ret;
}
}
}
}
Seventh, I had to add the CSDL, MSL and SSDL files to my host project to make things work. Still need to think about a better way to do this:
<connectionStrings>
<add name="DBinsor.Svc.WCF.DataAccess.Properties.Settings.WindsorDataBaseConnectionString"
connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\WindsorDataBase.mdf;Integrated Security=True;User Instance=True"
providerName="System.Data.SqlClient" />
</connectionStrings>Finally, Here is the End Product:
Both of these technologies are very powerful ways of implementing object to relational mapping. With LINQ to SQL, I feel it should be built on top of “views” so when one makes table changes the whole system doesn’t come crashing down. The Entity Framework seems to cover such scenarios in its mapping functionality.
However, neither seems to place nice in the n-tier model. That is, in which DLL should the EDMX or the DBML files belong? In one sense they do data access and in another they define business entities. On the one hand, I suppose one could put them in the data access layer and use business logic to convert those entities to ones defined in the business tier. Yet, that seems like a lot of work and bit un-refactored. On the other hand, we could put them in the business layer, but then we are doing data access from the business layer.
I would like to see a system where the data access is decoupled from the entities. For now, I am going to add these files to the data access layer. Furthermore, I am going to add the Data Contracts from my service layer to my business layer: not really happy about that. However, this will allow me the ability to use my business layer as a translator to expose my entities to the Silverlight frontend.
I could add the data access to my service implementation project, but I think it is better to do such translations in the business layer. Obviously, we could build duplicate entities in the business layer and translate twice, then again to much work and not that refactored.
I am using Windows XP Professional, Visual Studio 2008 Professional, IE 7.0 and Silverlight 2.0. The weird thing is I must delete my history every time in IE before I can view changes to my Silverlight application. I am assuming that is caching the XAP file in the browser and not reloading it when I make changes. I am sure there is a work around, but I have not had time to look for it. Any ideas?
It has been a couple weeks since my last post. As with many juggling family, career, socializing and hobbies can be quite a circus act. Nonetheless, the DBinsor solution has not yet reached a critical mass for usability.
It is great that one can pull the configuration from the database, but how does one put it there in the first place. Moreover, this process of insertion should be intuitive as well as allow for a holistic view of the data.
The end user of choice for DBinsor would be a system which utilized a plug in methodology meshed with a SOA topology. More specifically, one who utilizes services contracts where the implementation is defined by configuration settings. Thus utilizing DBinsor as a centralized configuration store should be quite appealing.
With this type of user in mind, a web user interface is the only sensible approach. For example, an administrator could seamlessly change configurations of any service from any computer with accessibility to the DBinsor server without installing a windows client.
We could have chosen web forms or the new model view controller framework; however Silverlight 2.0 seems the most intriguing. Moreover, we get the chance to work with XAML instead of HTML and Java Script. The “Learn” section has been quite helpful in the process of learning Silverlight.
We will post something once we have basic functionality working.
We uploaded the working code to the Code Gallery Site. This should allow readers of this blog the ability to see exactly what is happening underneath the hood. One very interesting use of this application is a centralized configuration repository. That is because of the parameters feature of the Windsor Library, a user should use those instead of a configuration file.
If anyone is interested in contributing to this project, please send me an email. The next features will include:
· A web GUI to access the database
· A windows application using reflection to auto generate data from an assembly
· Using card space to add security
· Exposing all the features of the container.
· Performance Enhancements
· And others.
We have also added Code Gallery to Navigation Section.
To test this, we decided to setup an interface and two derived classes. Then we added corresponding data to the database (we will build an intuitive graphical user interface eventually). Finally, we used the Container Singleton class to resolve our types and print out the results.
Class Diagram:

Database:
Windsor Component View
|
Lookup Name |
Namespace |
Contract |
Implementation |
Component Id |
Contract Id |
|
|
|
|
|
|
|
Test1 |
DBinsor.Svc.WCF.Client |
IMath |
Add |
1844d2e0-455e-4d44-a9ff-1c63f78e407b |
0aa71152-91d4-4e8f-a4a0-4124a98e2851 |
|
Test1 |
DBinsor.Svc.WCF.Client |
IMath |
Subtract |
5c3ee79a-926c-4438-8391-44a437bd8f47 |
0aa71152-91d4-4e8f-a4a0-4124a98e2851 |
Windsor Parameters View
|
Component Id |
Contract Id |
Parm Name |
Default |
Override |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5c3ee79a-926c-4438-8391-44a437bd8f47 |
0aa71152-91d4-4e8f-a4a0-4124a98e2851 |
a |
1 |
13 |
|
5c3ee79a-926c-4438-8391-44a437bd8f47 |
0aa71152-91d4-4e8f-a4a0-4124a98e2851 |
b |
2 |
NULL |
|
1844d2e0-455e-4d44-a9ff-1c63f78e407b |
0aa71152-91d4-4e8f-a4a0-4124a98e2851 |
a |
1 |
NULL |
|
1844d2e0-455e-4d44-a9ff-1c63f78e407b |
0aa71152-91d4-4e8f-a4a0-4124a98e2851 |
b |
2 |
NULL |
Classes:
Test:
IMath proxy = ContainerSingleton.Instance.Resolve<Add, IMath>();
Console.WriteLine(proxy.Calculate().ToString());
proxy = ContainerSingleton.Instance.Resolve<Subtract, IMath>();
Console.WriteLine(proxy.Calculate().ToString());
Console.WriteLine(ContainerSingleton.Instance.Xml);
Result:
3
11
<configuration>
<components>
<component id="DBinsor.Svc.WCF.Client.Add"
service="DBinsor.Svc.WCF.Client.IMath, DBinsor.Svc.WCF.Client" type="DBinsor.Svc.WCF.Client.Add, DBinsor.Svc.WCF.Client">
<parameters>
<a>1</a>
<b>2</b>
</parameters>
</component>
<component id="DBinsor.Svc.WCF.Client.Subtract"
service="DBinsor.Svc.WCF.Client.IMath, DBinsor.Svc.WCF.Client" type="DBinsor.Svc.WCF.Client.Subtract, DBinsor.Svc.WCF.Client">
<parameters>
<a>13</a>
<b>2</b>
</parameters>
</component>
</components>
</configuration>
One thing we have found useful over the years is to wrap a service proxy in a public interface Dynamic Link Library. Though this in one sense may contradict the idea of Service Oriented Architecture (SOA); in another sense it holds up the idea of refactoring.
In this project, we have created a singleton that loads the configuration file from the database. Furthermore, this singleton aggregates Windsor Container for easy of accessibility throughout ones program. One draw back is (depending on usage) the load time of ones program may suffer due to Service / Database Access.
Previously, we stated that DBinsor required each class to implement an interface. Thus, we ensured this by added our custom resolve method in the singleton. public T Resolve<T, S>()
where T : class, S
{
return this._container.Resolve<S>(typeof(T).ToString()) as T;
}
In future releases of this library, we will add more methods to the singleton to provide access to other functionality of the Windsor Container.
Again, we used the factory methodology to allow for multiple sources for the Windsor Container. That is, we plan to allow a user to pick from our database service, an application configuration file, a web configuration file or a standalone xml file as their source for the singleton.
The public interface uses the “app.config” or the “web.config” files for three things: lookup name, resource source and service binding. Here is a sample:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="LookupName" value="Test1" />
<add key="ResourceSource" value="Database" />
</appSettings>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="ConfigSvcEndPoint" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:3837/DBinsor.Svc.WCF.Host/Configuration.svc"
binding="basicHttpBinding" bindingConfiguration="ConfigSvcEndPoint"
contract="ConfigurationServiceProxy.ConfigurationServiceContract"
name="ConfigSvcEndPoint" />
</client>
</system.serviceModel>
</configuration>
In the last post, we purposely did not address the core question of how does one generate the xml configuration from the database. This used to require quite a bit of code; however, we have LINQ (praise the Microsoft Gods). I am by no means a LINQ expert, nevertheless I know enough to make it work.
The code is pretty straight forward; we used LINQ to SQL to select all rows from the database where the lookup name equals our requested name. Then we used LINQ to XML to put those rows into an XML file. This was almost too trivial of a task. using System;
using System.Linq;
using System.Xml.Linq;
using DBinsor.Svc.WCF.BusinessEntities;
using DBinsor.Svc.WCF.DataAccess;
namespace DBinsor.Svc.WCF.BusinessLogic
{
public class ResourceFromDatabase : IResource
{
public ConfigurationEntity GenerateXml(ConfigurationEntity entity)
{
if (entity == null)
{
throw new ArgumentException("Configuration Entity Was Null.", "entity");
}
if (string.IsNullOrEmpty(entity.LookupName) == true)
{
throw new ArgumentException("Lookup Name Was Null or Empty.", "entity");
}
using (DBinsorViewDataContext windsorDataAccess =
new DBinsorViewDataContext())
{
entity.Xml = new XElement("configuration",
new XElement("components",
from components in windsorDataAccess.WindsorComponents
where components.LookupName == entity.LookupName
orderby components.ImplementationName
select new XElement("component",
AddRequiredAttributes("id", components.Namespace + "." + components.ImplementationName),
AddRequiredAttributes("service", components.Namespace + "." + components.ContractName + ", " + components.Namespace),
AddRequiredAttributes("type", components.Namespace + "." + components.ImplementationName + ", " + components.Namespace),
AddOptionalAttributes("inspectionBehavior", components.InspectionBehavior),
AddOptionalAttributes("lifestyle", components.Lifestyle),
AddOptionalAttributes("customLifestyleType", components.CustomLifestyleType),
AddOptionalAttributes("initialPoolSize", components.InitialPoolSize.ToString()),
AddOptionalAttributes("maxPoolSize", components.MaxPoolSize.ToString()),
AddParameters(components.ComponentId, components.ContractId)
)
)
);
}
return entity;
}
private static XAttribute AddRequiredAttributes(string name, string value)
{
return new XAttribute(name, value);
}
private static object AddOptionalAttributes(string name, string value)
{
if (string.IsNullOrEmpty(value) == true)
{
return null;
}
return new XAttribute(name, value);
}
private static XElement AddParameters(Guid componentId, Guid contractId)
{
using (DBinsorViewDataContext windsorDataAccess =
new DBinsorViewDataContext())
{
return new XElement("parameters",
from parameters in windsorDataAccess.WindsorParmaters
where (parameters.ComponentId == componentId && parameters.ContractId == contractId)
orderby parameters.ParmName
select new XElement(parameters.ParmName,
ReturnDefaultOrOverride(parameters.ParmDefault, parameters.OverrideValue))
);
}
}
private static string ReturnDefaultOrOverride(string defaultValue, string overrideValue)
{
if (string.IsNullOrEmpty(overrideValue) == false)
{
return overrideValue;
}
return defaultValue;
}
}
}
The only concern I have is in the “AddParameters” function; does it make a round trip to the database on every select? I think it probably does; thus this may be a huge performance bottleneck. However, first we should build for proof of concept. Then we can go back and optimize.
Quite shockingly, we have etched out an n-tier service oriented system without writing a single line of code. Moreover, we are following best practices to decouple the data layer, business layer, service layer and presentation layer. Generally, we do this for two reasons: one, to promote the idea of separation of concerns and two, to allow for future flexibility when addressing change sets.
The wiring process can be summed up as adding business entities and logic to link the data layer to the service layer. Business entities should be though of as objects that hold state. Business logic should be thought of functions or processes that affect business entities. This is gray definition, because in some cases business entities might have functionality. An example of a business object is a person; who has a name and an age. However, this person may have an internal process called heartbeat: thus the grayness.
We will define one business entity (for now) called “ConfigurationEntity”. This entity will have two properties: “LookupName” and “Xml”. The “LookupName” will be used to find the castle configuration in the database. The “Xml” will hold the dynamically generated xml configuration from the database.
Before we proceed, generally I would unit test at this point. Test Driven Development (TDD) states: we should write tests first then code. However, because it would require the use of mocks, I will refrain until a later post.
Next, we will use a factory pattern to generate the xml from the database. Again, we are choosing a design that provides for flexibility during future change sets. The factory uses an enumeration to decide which type of process to return.
Finally, we have to generate translators to and from our service layer data contracts to our business layer business entities. These translators will be used in our service implementation to allow access to our business logic.
Class Diagram:

Factory: namespace DBinsor.Svc.WCF.BusinessLogic
{
public static class ResourceFactory
{
public static IResource GenerateResouce(ResourceLocations location)
{
switch (location)
{
case ResourceLocations.Database:
return new ResourceFromDatabase();
default:
throw new ArgumentException("Location Not Supported.", "location");
}
}
}
}Finally, we have to generate translators to and from our service layer data contracts to our business layer business entities. These translators will be used in our service implementation to allow access to our business logic. namespace DBinsor.Svc.WCF.ServiceImplementation
{
public static class TConfigurationEntityAndConfigurationResponse
{
public static ConfigurationResponse Convert(ConfigurationEntity from)
{
ConfigurationResponse to = new ConfigurationResponse();
to.ConfigurationPart = new ConfigurationPart();
to.ConfigurationPart.XmlConfiguration = new XmlConfiguration();
to.ConfigurationPart.XmlConfiguration.Config = from.Xml.ToString();
return to;
}
}
}namespace DBinsor.Svc.WCF.ServiceImplementation
{
public static class TConfigurationEntityAndConfigurationRequest
{
public static ConfigurationEntity Convert(ConfigurationRequest from)
{
return new ConfigurationEntity(from.CastleId.LookupName);
}
}
}namespace DBinsor.Svc.WCF.ServiceImplementation
{
public partial class ConfigurationService
{
public override ConfigurationResponse GetConfigurationDemand(ConfigurationRequest request)
{
IResource businessLogic = ResourceFactory.GenerateResouce(ResourceLocations.Database);
return TConfigurationEntityAndConfigurationResponse.Convert(
businessLogic.GenerateXml(
TConfigurationEntityAndConfigurationRequest.Convert(
request)));
}
}
}
At first glance these two new data access technologies seem to fulfill a common purpose. Though, from my basic understanding the ADO.NET Entity Framework [EF] acts more like an Object Relational Mapping [ORM] tool, where as the LINQ to SQL [LTOS] acts similar to an ADO.NET Dataset. This is my first observation and will most likely be discredited through further inspection.
Functionally, we are trying to use a technology to extract, insert, modify and delete from our database. Thus, it seems either technology would be well suited. For a production system, we would lean towards LTOS because EF is still in a beta 3 version. However, because we view this project as a learning exercise, we will employee both technologies.
Due to the fact the EF is much more like an ORM; we will use it for our data access to the tables of the database. Consequently, we will use LTOS for the data access associated with the views of the database. Basically, the idea is if we change the underlying table structure, our business object to relational mapping should not have to change.
In the above example, this should hold true (pending that EF does have a flexible Object to Relational Mapping portion). We will leave this argument unjustified for the moment, because most likely we will have to change the database later on.
ADO.NET Entity Framework Table Map:

LINQ to SQL View Map:

Component: SELECT dbo.Castle.Name AS LookupName, dbo.Contracts.Namespace, dbo.Implementations.Id, dbo.Contracts.Interface AS ContractName,
dbo.Implementations.Name AS ImplementationName, dbo.Components.InspectionBehavior, dbo.Components.Lifestyle,
dbo.Components.CustomLifestyleType, dbo.Components.InitialPoolSize, dbo.Components.MaxPoolSize, dbo.Components.Id AS ComponentId,
dbo.Contracts.Id AS ContractId
FROM dbo.Castle INNER JOIN
dbo.Components ON dbo.Castle.Id = dbo.Components.CastleId INNER JOIN
dbo.Implementations ON dbo.Components.ImplementationId = dbo.Implementations.Id INNER JOIN
dbo.Contracts ON dbo.Implementations.ContractId = dbo.Contracts.Id
Parameter: SELECT dbo.Components.Id AS ComponentId, dbo.Contracts.Id AS ContractId, dbo.ContractParameters.Name AS ParmName,
dbo.ContractParameters.DefaultValue AS ParmDefault, dbo.ComponentParameters.OverrideValue
FROM dbo.Components INNER JOIN
dbo.Implementations ON dbo.Components.ImplementationId = dbo.Implementations.Id INNER JOIN
dbo.Contracts ON dbo.Implementations.ContractId = dbo.Contracts.Id INNER JOIN
dbo.ContractParameters ON dbo.Contracts.Id = dbo.ContractParameters.ContractId LEFT OUTER JOIN
dbo.ComponentParameters ON dbo.Components.Id = dbo.ComponentParameters.ComponentId AND
dbo.ContractParameters.Id = dbo.ComponentParameters.ContractParameterId
Upon those who step into the same rivers flow other and yet other waters.
All things . . . are in flux like a river.
In my estimation, embracing change has revolutionized our conception of software architecture. With the advent of agile methodologies, we are consistently designing for change. Moreover, my team develops core functionality, deploys and welcomes change requests.
The question then becomes how does one code for change? Some of today’s biggest buzz words can give a clue: Test Driven Development (TDD), Domain Driven Design (DDD), Inversion of Control (IOC) and Service Oriented Architecture (SOA).
Test Driven Development, used correctly, can mitigate bugs during the implementation of change sets. Furthermore, DDD specifies a guide to use design patterns to implement loosely couple objects. In the same vein Inversion of Control, as shown in earlier posts, greatly reduces dependencies between objects. Finally, Service Oriented Architecture defines architecture to house loosely coupled systems.
In summation, we should embrace change throughout our design, implementation, deployment and changes set resolution.
I normally utilize the “Web Service Software Factory” to structure and implement my services. This package greatly decreases the time spent on the mundane tasks of exposing your business logic to the service layer.
One could argue that exposing business logic is quite simple, add a WCF service to your project and write your business logic in the *.svc file. However, we are here to write loosely coupled code. To this end, one can use multiple dynamic link libraries (.dll) to organize one code. Moreover, by judicially choosing where objects belong, one can apply the principles of separations of concerns.
The “hands on lab” for the web service factory is top notch. The modeling edition allows one to use a graphical approach to define data and services contacts quickly and correctly. Below are the data contract and the service contract files needed to expose a service with a DBinsor configuration file. Furthermore, I have included the projects contained in the solution file.
Data Contract:

Service Contract:

Solution:
The MSDN Code Gallery is finally setup. Prior to uploading a code sample, I would like to make a bit of headway in the documentation process.
Prior to starting this conversation, I will make the assumption that one has completed the “Getting Started Project”. Moreover, in the RC3 Documentation, I would recommend reading the “Concepts” and “User Guides” sections.
Last week I uploaded a database diagram without much explanation. I plan to rectify that shortcoming in this post. When perusing the Castle Windsor documentation, the Windsor configuration reference was extremely helpful in the design of the database.
Reading the tags in a top down manner, I decided the “includes tag” was not necessary in a database scenario. The “includes tag” is useful when one does not want to keep all configurations in one file. However, since we are keeping all configurations in a centralized database, the use of multiple configuration files is unnecessary. Similarly speaking, “global properties” are superfluous because of the database. However, the conception of “global properties” will be addressed on the database graphical user interface (GUI).
“Facilities” are very powerful in that they allow one to extend the container. Nonetheless, they are out of scope in this preliminary version of D-Binsor. Similarly, the concept of “interceptors” will be left for future version of this library.
The heart and soul of this configuration file lies in the use of “components” coupled with “parameters”. With this in mind, the first table I created was the Contracts Table.
In general, I create a primary key, “Id”, for all my tables to make table to table relationships easier. Many would not name the primary key for each table the same, though I found with LINQ to SQL to find the unique identifies in the corresponding object is much easier.
In the theme of trying to be succinct, I will explain the key design choices I made. My first large choice was that every implementation must have a contract. Windsor does allow for one to register classes which have no associated interface. However, I feel that in a large scale SOA systems, where “D-Binsor” will be most useful, there is very little drawback to interface programming. Furthermore, the extensibility benefits from interface programming, for example “Mocking”, are quite compelling.
This decision allows for function parameters to only be defined on a contract basis. Thus, we have concluded the right side of the diagram. Before we discuss the left side, one issue with this design is that one could create two contracts in the same namespace with the same signature and receive no database warning. Obviously, that is unacceptable in the programming space [we will have to tackle this problem in the business layer].
One of the goals, beyond data storage, of a database should be data integrity. That is the database should not allow one to enter data which breaks business rules.
The left side of the diagram allows one or more castle configuration files to utilize the contract implementation structure defined above. Generally, one would create a new configuration file by adding data to the castle table. From there one could register components and component parameters to generate the correct configuration file.
To reiterate, one of the goals of a database should be data integrity. In that vein, we should utilize non-null foreign key relationships. For example, the implementation table must have a non-null contract id. Moreover, we should use a unique key when necessary. Though it is not visible in the diagram, in the contract parameters table the combination of the contract id and name fields should be unique.
We have decided to upload the source code for this project to the MSDN Code Gallery. The code gallery site should be functional by April 6th, 2008. If you have an interest in joining this project please contact me, by email, through the blog site.
Here is my preliminary table schema. Tomorrow we will probe into how my assumptions influenced its design.

A well written program must implore the services of persistence. Many would argue not in all cases; I disagree. I personally cannot think of a program that would not benefit from a configuration file instead of hard coding settings. Yes, the configuration file is a means of persisting load settings. Moreover, event logs are also crucial to find user aborted exceptions.
Though most would think database, xml file or file system, my view of persistence is anything that allows continuity between sessions of you application. Before I delve deeply into what SQL Express can provide to this application [my next blog entry], I would like explore the two aforementioned concepts.
First, one should use an external configuration source to abstract ones code. The avoidance of recompilation and deployment provides for agility and stability. We will see later how I see Castle Windsor helping in this process.
Second, never swallow exceptions. By swallowing exceptions, I mean try catch without alerting the user. Moreover, write the exception to the event log; lost exceptions don’t help the debugging process. In general one should throw an exception early and cleanly allow for appropriate remedies. This is concept best taught by example.
There are many takes on the agile development process: SCRUM, TDD and Extreme Programming to name a few. One of the most important, in my estimation, from the agile manifesto is: “Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale.”
With this in mind, my first function is simply to design a database and extract a compatible IResource for the Castle Windsor Container. In actuality this process was quite trivial [a Sunday afternoon] with the new technologies of .Net 3.5. Moreover, it will take me much longer to explain what I did; than actually do it.
In my next post, I will delve into the database design.
These concepts have been around for quite a few years: from Martin Fowler’s description to this month’s MSDN magazine’s tutorial. Stefano Mazzocchi wrote: “IOC is about enforcing isolation.” Not many would argue that the n-tier architecture is a bad thing, however have you ever tried instantiating one class from the business tier by itself?
To facilitate such a scenario, the idea of dependency injection and containers comes into play. One example of such a tool for .Net is Castle Windsor. This open source project allows a user to “Separate Concerns” by injecting dependencies through an xml specification.
As with many, I have a love hate relationship with xml configuration files. For example, Oren Eini has created Binsor to combat his xml irritations. My thought is instead; let us put it in a database.
I plan to use some new interesting technologies to do this. The idea is to use SQL Express with LINQ to SQL to handle the object relational mapping. Then I will use LINQ to XML to auto generate an XML document [I could probably bypass the Xml Interpreter altogether if wanted]. From there I will use WCF to expose the generated xml as a service. Once this is done, we will talk about GUI’s to update the database.
So let’s get started.
I had a professor in graduate school who once said that Computer Science, as an educational institution, is backwards. Furthermore, he went on to say that in no other field do professors teach without practical experience. For example, a professor of trial law would not teach how to cross examine a defendant if one did not have the corresponding experience. Nor would a professor of surgery explain the procedure of a heart transplant, if one did not have multiple transplants under one’s belt.
Obviously, the previous statement is quite general and a bit drastic. Nonetheless, as I interview prospective employees I am very disheartened by their conceptual knowledge of the field.
Out stems a few questions:
How has our industry come to such a state?
How can we educate better?
As a .Net Developer, we are in a whirlwind of new ideas, technologies and practices. Thus, it is an exciting time as well as a crucial time to educate as we do along.
The purpose of my blog is to educate on ideas, technologies, and practices from my personal experiences.
|