16 November 2009
Writing an EventBroker
On a project I'm working on with my friend Michael, we need a web page to be build from independent modules - independent in the sense that they have no direct dependency on any other module and that they may operate autonomously. A lose coupling strategy for the various UI elements you could call it.
We need this kind of flexibility because the users of the system must be able to pick and choose any module, or any number of modules, for any given page, dynamically - that is, without the need for a developer to wire everything up in the code behind. They should be able to select the modules they want and the modules should function autonomous. The modules should also be able to send messages to other modules when needed, without knowledge of each other.
The way I went about achieving this was by writing an EventBroker. An EventBroker can be considered an implementation of the Publisher/Subscriber pattern or a sub-pattern or derivative thereof.
It is obvious, that to achieve loosely coupled modules that knows nothing of the other modules, yet are able to send messages to each other, we must move the coupling or change its direction to an intermediate component. This is the role of the EventBroker.
An example is in place. I have two modules. When the UpdateContent method in the first module is executed, I want the second module to be notified and do something about it.
I use well named interfaces to express the type of message send.
The SubscriberModule subscribe to messages of type UpdateContentEvent and assigns a messagehandler, UpdateContentHandler, to handle the message when or if it occur.
The PublisherModule first builds some event arguments, then publishes the event, UpdateContentEvent, and supplies a reference to itself as well as the arguments.
That is basically it. The two modules know nothing of each other, but are able to send and receive messages from and to each other through the EventBroker.
Some considerations:
This EventBroker implementation is static and as such represent the strongest coupling one can have between components. In this case I find it acceptable and consider it part of the infrastructure of the system we are building. It is possible to change the implementation slightly and inject the EventBroker into the classes that use it, or hide it behind a factory, but at this point I'm satisfied with the coupling it represents.
The implementation only allow modules to send and receive messages in a synchronous manner. This is all I need at the moment, but at some point it may need to support asynchronous messaging. If this need emerge, I'll consider a true message bus instead.
The implementation allow for any number of publishers and subscribers. I've wrapped the event handling Action delegate in a WeakReference so that the EventBroker does not become a greedy memory-clutching hub.
In truth the EventBroker mediates messages, not events in the sense of .NET events. In this implementation I switch between the terms event and message. This can be cause for misunderstandings. In the next version I'll remedy that...
Lastly, the EventBroker is thread safe.
And here is the EventBroker code:
We need this kind of flexibility because the users of the system must be able to pick and choose any module, or any number of modules, for any given page, dynamically - that is, without the need for a developer to wire everything up in the code behind. They should be able to select the modules they want and the modules should function autonomous. The modules should also be able to send messages to other modules when needed, without knowledge of each other.
The way I went about achieving this was by writing an EventBroker. An EventBroker can be considered an implementation of the Publisher/Subscriber pattern or a sub-pattern or derivative thereof.
It is obvious, that to achieve loosely coupled modules that knows nothing of the other modules, yet are able to send messages to each other, we must move the coupling or change its direction to an intermediate component. This is the role of the EventBroker.
An example is in place. I have two modules. When the UpdateContent method in the first module is executed, I want the second module to be notified and do something about it.
I use well named interfaces to express the type of message send.
public interface UpdateContentEvent {}
The SubscriberModule subscribe to messages of type UpdateContentEvent and assigns a messagehandler, UpdateContentHandler, to handle the message when or if it occur.
public class SubscriberModule
{ public SubscriberModule() { EventBroker.Subscribe<UpdateContentEvent>(UpdateContentHandler);
}
private void UpdateContentHandler(object sender, EventArgs e)
{ var args = e as UpdateContentEventArgs;
if(args != null)
{ string content = args.Content; // perform some update with content }
}
}
The PublisherModule first builds some event arguments, then publishes the event, UpdateContentEvent, and supplies a reference to itself as well as the arguments.
public class PublisherModule
{ public void DoUpdateContent()
{ EventArgs args = new UpdateContentEventArgs {Content = "Some content to be updated"};
EventBroker.Publish<UpdateContentEvent>(this, args);
}
}
That is basically it. The two modules know nothing of each other, but are able to send and receive messages from and to each other through the EventBroker.
Some considerations:
This EventBroker implementation is static and as such represent the strongest coupling one can have between components. In this case I find it acceptable and consider it part of the infrastructure of the system we are building. It is possible to change the implementation slightly and inject the EventBroker into the classes that use it, or hide it behind a factory, but at this point I'm satisfied with the coupling it represents.
The implementation only allow modules to send and receive messages in a synchronous manner. This is all I need at the moment, but at some point it may need to support asynchronous messaging. If this need emerge, I'll consider a true message bus instead.
The implementation allow for any number of publishers and subscribers. I've wrapped the event handling Action delegate in a WeakReference so that the EventBroker does not become a greedy memory-clutching hub.
In truth the EventBroker mediates messages, not events in the sense of .NET events. In this implementation I switch between the terms event and message. This can be cause for misunderstandings. In the next version I'll remedy that...
Lastly, the EventBroker is thread safe.
And here is the EventBroker code:
public static class EventBroker
{ static readonly IList<KeyValuePair<Type, WeakReference>> eventsSubscribedTo = new List<KeyValuePair<Type, WeakReference>>();
public static void Subscribe<TEventType>(Action<object, EventArgs> eventHandler)
{ lock (eventsSubscribedTo) eventsSubscribedTo.Add(new KeyValuePair<Type, WeakReference>(typeof(TEventType), new WeakReference(eventHandler)));
}
public static void Publish<TEventType>(object sender, EventArgs e)
{ lock (eventsSubscribedTo) { RemoveGarbageCollectedEventHandlers();
for (int i = 0; i < eventsSubscribedTo.Count; i++)
{ if (eventsSubscribedTo[i].Key == typeof(TEventType))
{ var eventHandler = eventsSubscribedTo[i].Value.Target as Action<object, EventArgs>;
if(eventHandler != null)
eventHandler(sender, e);
}
}
}
}
private static void RemoveGarbageCollectedEventHandlers()
{ for (int i = 0; i < eventsSubscribedTo.Count; i++)
{ KeyValuePair<Type, WeakReference> pair = eventsSubscribedTo[i];
WeakReference value = pair.Value;
var eventHandler = value.Target as Action<object, EventArgs>;
if (eventHandler == null)
eventsSubscribedTo.Remove(pair);
}
}
public static void Unsubscribe<TEventType>(Action<object, EventArgs> eventHandler)
{ lock (eventsSubscribedTo) for (int i = 0; i < eventsSubscribedTo.Count; i++)
{ KeyValuePair<Type, WeakReference> pair = eventsSubscribedTo[i];
Type eventType = pair.Key;
WeakReference weakReference = pair.Value;
var handler = weakReference.Target as Action<object, EventArgs>;
if (eventType == typeof(TEventType) && handler == eventHandler)
eventsSubscribedTo.Remove(pair);
}
}
public static void Clear()
{ lock (eventsSubscribedTo) eventsSubscribedTo.Clear();
}
}
Please feel free to suggest improvement or errors I have not detected.
Labels: Advanced Programming, C#
28 March 2009
Working with percent (%) in a fluent manner
The Ruby programming language has some really human readable syntax. The canonical example is properly: 20.minutes.ago, which in C# terms would require several lines of code that would be much more difficult to read.
In C# 3.0 we got Extension Methods, which is basically syntactic sugar, that provide a more readable syntax for LINQ method syntax, which is basically chained monads.
For the past few months I've been playing around with the C# language, trying to "squeeze" readability out of it, using arithmetic- and implicit operator overloading in union with extension methods. It has produced a lot of readable, but completely useless code. But a couple of weeks ago I ran into a usable challenge: making percent (%) calculation more easy to read and use. Here's what I ended up with so far.
Here's how you can instantiate and initialize the Percent type. This part is done using implicit operator overloading:
And some examples on how you could use it.
This is achieved using arithmetic operator overloading:
The extension methods used to provide the fluent syntax, 10.pct(), are trivial:
Lastly we have the Percent class. It is rather long, but a lot of repetitious code is needed to overload the many combination's of the arithmetic operators as well as the implicit operators:
A word of caution. If you plan on using this code, make sure to make an extensive test suite first. The code presented here is only for demonstration purposes and due to laziness I have not produced exhaustive tests myself, I'll leave that up to you dear reader.
If you find errors in the logic of the code - which you most properly will - I'll be very interested in hearing from you.
In C# 3.0 we got Extension Methods, which is basically syntactic sugar, that provide a more readable syntax for LINQ method syntax, which is basically chained monads.
For the past few months I've been playing around with the C# language, trying to "squeeze" readability out of it, using arithmetic- and implicit operator overloading in union with extension methods. It has produced a lot of readable, but completely useless code. But a couple of weeks ago I ran into a usable challenge: making percent (%) calculation more easy to read and use. Here's what I ended up with so far.
Here's how you can instantiate and initialize the Percent type. This part is done using implicit operator overloading:
Percent p1 = 10; Percent p2 = 12.0; Percent p3 = 18.025; Percent p4 = "10.1";
Percent p5 = "10,2";
Percent p6 = new Percent("20,02");
Percent p7 = new Percent(22.2);
Percent p8 = 10.pct(); Percent p9 = 10.2.pct(); Percent p10 = 15.4m.pct(); Percent p11 = "0.4".pct();
This is achieved using arithmetic operator overloading:
decimal result1 = 100 + 10.pct(); // result1 equals 110
decimal result2 = 100 - 10.pct(); // result2 equals 90
decimal result3 = 100 * 10.pct(); // result3 equals 10
decimal result4 = 100 / 10.pct(); // result4 equals 1000
// semantics are somewhat quirky here: 10% - value could mean two things decimal result5 = 10.pct() + 100; // result5 equals 110
decimal result6 = 10.pct() - 100; // result6 equals -90
decimal result7 = 10.pct() * 100; // result7 equals 10
decimal result8 = 10.pct() / 100; // result8 equals 1000
decimal result9 = 100 + 10.pct() - 50.pct(); // result9 equals 55
decimal result10 = 10.pct() - 100 - 50.pct(); // result10 equals -45
decimal result11 = 100 / 5.pct() + 50 * 10.pct(); // result11 equals 2005
decimal result12 = 10.pct() + 100 - 5.pct() / 20 * 10.pct(); // result12 equals 109.99975
decimal result13 = ( 1.pct() + 9.pct() ) * 100; // result13 equals 10
decimal result14 = ( 1.pct() - 9.pct() ) * 100; // result14 equals -8
decimal result15 = 5.pct() * 5.pct() * 100; // result15 equals 0.25
decimal result16 = 10.pct() / 2.pct() * 100; // result16 equals 500
decimal result17 = 100 - "5".pct() + 20 * "200".pct(); // result17 equals 135
The extension methods used to provide the fluent syntax, 10.pct(), are trivial:
public static class ExtensionMethods
{ public static Percent pct(this decimal value)
{ return new Percent(value);
}
public static Percent pct(this double value)
{ return new Percent(value);
}
public static Percent pct(this int value)
{ return new Percent(value);
}
public static Percent pct(this string value)
{ return new Percent(value);
}
}
Lastly we have the Percent class. It is rather long, but a lot of repetitious code is needed to overload the many combination's of the arithmetic operators as well as the implicit operators:
public class Percent
{ private readonly decimal _decimal;
public Percent(decimal percent)
{ _decimal = percent;
PreventNegativePercent(_decimal);
}
public Percent(double percent)
{ _decimal = (decimal)percent; PreventNegativePercent(_decimal);
}
public Percent(int percent)
{ _decimal = percent;
PreventNegativePercent(_decimal);
}
public Percent(string percent)
{ _decimal = ParseStringToDecimal(percent);
PreventNegativePercent(_decimal);
}
public override string ToString()
{ return _decimal.ToString(); }
private static void PreventNegativePercent(decimal _decimal)
{ if (_decimal < 0) throw new ArgumentException("Negative percent not allowed");
}
private decimal Value
{ get { decimal result = _decimal/100m; return result; }
}
private static decimal ParseStringToDecimal(string value)
{ value = value.Replace('.', ',');
decimal parsedValue; if (decimal.TryParse(value, out parsedValue))
return parsedValue; throw new ArgumentException("string could not be parsed to decimal", value);
}
#region Ahritmetic operator overload for Percent public static decimal operator *(Percent left, Percent right)
{ decimal result = left.Value * right.Value; return result; }
public static decimal operator +(Percent left, Percent right)
{ decimal result = left.Value + right.Value; return result; }
public static decimal operator -(Percent left, Percent right)
{ decimal result = left.Value - right.Value; return result; }
public static decimal operator /(Percent left, Percent right)
{ decimal result = left.Value / right.Value; return result; }
#endregion #region Ahritmetic operator overload for decimal public static decimal operator *(Percent left, decimal right)
{ decimal result = left.Value * right; return result; }
public static decimal operator *(decimal right, Percent left)
{ decimal result = left.Value*right; return result; }
public static decimal operator +(Percent left, decimal right)
{ decimal result = (left.Value*right) + right; return result; }
public static decimal operator +(decimal right, Percent left)
{ decimal result = (left.Value*right) + right; return result; }
public static decimal operator -(Percent left, decimal right)
{ decimal result = (left.Value*right) - right; return result; }
public static decimal operator -(decimal right, Percent left)
{ decimal result = right - (left.Value*right); return result; }
public static decimal operator /(Percent left, decimal right)
{ decimal result = left.Value/right; return result; }
public static decimal operator /(decimal right, Percent left)
{ decimal result = right/left.Value; return result; }
#endregion #region Ahritmetic operator overload for double public static decimal operator *(Percent left, double right)
{ decimal result = left.Value*(decimal) right;
return result; }
public static decimal operator *(double right, Percent left)
{ decimal result = left.Value*(decimal) right;
return result; }
public static decimal operator +(Percent left, double right)
{ decimal result = (left.Value * (decimal)right) + (decimal)right;
return result; }
public static decimal operator +(double right, Percent left)
{ decimal result = (left.Value * (decimal)right) + (decimal)right;
return result; }
public static decimal operator -(Percent left, double right)
{ decimal result = (left.Value * (decimal)right) - (decimal)right;
return result; }
public static decimal operator -(double right, Percent left)
{ decimal result = (decimal)right - (left.Value * (decimal)right);
return result; }
public static decimal operator /(Percent left, double right)
{ decimal result = left.Value / (decimal)right;
return result; }
public static decimal operator /(double right, Percent left)
{ decimal result = (decimal)right / left.Value;
return result; }
#endregion #region Ahritmetic operator overload for int public static decimal operator *(Percent left, int right)
{ decimal result = left.Value * right; return result; }
public static decimal operator *(int right, Percent left)
{ decimal result = left.Value * right; return result; }
public static decimal operator +(Percent left, int right)
{ decimal result = (left.Value * right) + right; return result; }
public static decimal operator +(int right, Percent left)
{ decimal result = (left.Value * right) + right; return result; }
public static decimal operator -(Percent left, int right)
{ decimal result = (left.Value * right) - right; return result; }
public static decimal operator -(int right, Percent left)
{ decimal result = right - (left.Value * right); return result; }
public static decimal operator /(Percent left, int right)
{ decimal result = left.Value / right; return result; }
public static decimal operator /(int right, Percent left)
{ decimal result = right / left.Value; return result; }
#endregion #region Ahritmetic operator overload for string public static decimal operator *(Percent left, string right)
{ decimal result = left.Value * ParseStringToDecimal(right); return result; }
public static decimal operator *(string right, Percent left)
{ decimal result = left.Value * ParseStringToDecimal(right); return result; }
public static decimal operator +(Percent left, string right)
{ decimal result = (left.Value * ParseStringToDecimal(right)) + ParseStringToDecimal(right); return result; }
public static decimal operator +(string right, Percent left)
{ decimal result = (left.Value * ParseStringToDecimal(right)) + ParseStringToDecimal(right); return result; }
public static decimal operator -(Percent left, string right)
{ decimal result = (left.Value * ParseStringToDecimal(right)) - ParseStringToDecimal(right); return result; }
public static decimal operator -(string right, Percent left)
{ decimal result = ParseStringToDecimal(right) - (left.Value * ParseStringToDecimal(right)); return result; }
public static decimal operator /(Percent left, string right)
{ decimal result = left.Value / ParseStringToDecimal(right); return result; }
public static decimal operator /(string right, Percent left)
{ decimal result = ParseStringToDecimal(right) / left.Value; return result; }
#endregion #region Implicit operators for decimal, double, int and string public static implicit operator Percent(decimal value)
{ return new Percent(value);
}
public static implicit operator Percent(double value)
{ return new Percent(value);
}
public static implicit operator Percent(int value)
{ return new Percent(value);
}
public static implicit operator Percent(string value)
{ decimal parsedString = ParseStringToDecimal(value); return new Percent(parsedString);
}
#endregion }
A word of caution. If you plan on using this code, make sure to make an extensive test suite first. The code presented here is only for demonstration purposes and due to laziness I have not produced exhaustive tests myself, I'll leave that up to you dear reader.
If you find errors in the logic of the code - which you most properly will - I'll be very interested in hearing from you.
Labels: C#, Code, Fluent interfaces
20 September 2008
Writing your own logger
There exists excellent logging tools for the .NET stack - Log4Net springs to mind (and a host of related implementations) - so writing your own might seem like a waste of time. Anyhow, a former student asked for a logger code example, so here's my home rolled version. Note that this implementation must be extended to be useful for anything other than the most trivial of logging needs. Read the code and you will see why.
The number of interfaces and classes might seem a bit much, but I have been bitten by the BDD bug and try to adhere to the Single Responsibility Principle, the Separation of Concerns principle and the Open/Closed principle.
Note: My CopyAsHtmlAddin for Visual Studio 2008 is not functioning at the moment. I'll change the code below as soon as possible.
First I'll show how it is used:
And here are the interfaces and the abstract class you must use to implement your own logging:
This is how you could implement your own logging using the interfaces and abstract class above:
That is it! Now you have a tiny logging framework that is easy to extend and easy to use.
The number of interfaces and classes might seem a bit much, but I have been bitten by the BDD bug and try to adhere to the Single Responsibility Principle, the Separation of Concerns principle and the Open/Closed principle.
Note: My CopyAsHtmlAddin for Visual Studio 2008 is not functioning at the moment. I'll change the code below as soon as possible.
First I'll show how it is used:
// I want to log the error message with three different logging strategies.
// This means that the error message below will be saved to ErrorLog1.xml
// then to ErrorLog2.xml and lastly it is saved to a MS Sql database
ILoggingStrategy xmlFile1 = new XmlFileStrategy(@"c:\ErrorLog1.xml");
ILoggingStrategy xmlFile2 = new XmlFileStrategy(@"c:\ErrorLog2.xml");
ILoggingStrategy sqlDb = new MsSqlDbStrategy(@"Driver={SQL Native Client};Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword;");
// The error message (must be extended to be useful)
IMessage errorMessage = new ErrorMessage();
errorMessage.Message = "File write failed. Access denied.";
// Instanciating the error logger with three distinct logging strategies
ILogger logger = new ErrorLogger(xmlFile1, xmlFile2, sqlDb);
logger.Log(errorMessage);
And here are the interfaces and the abstract class you must use to implement your own logging:
public interface ILogger
{
void Log(IMessage message);
}
public interface IMessage
{
string Message { get; set; }
}
public interface ILoggingStrategy
{
void Perform(IMessage message);
}
public abstract class AbstractLogger : ILogger
{
protected IList<ILoggingStrategy> loggingStrategies;
public AbstractLogger(params ILoggingStrategy[] loggingStrategy)
{
loggingStrategies = new List<ILoggingStrategy>(loggingStrategy);
}
public virtual void Log(IMessage message)
{
foreach (ILoggingStrategy strategy in loggingStrategies)
{
strategy.Perform(message);
}
}
}
This is how you could implement your own logging using the interfaces and abstract class above:
// Make a class that implements the IMessage interface
// This class will hold error information
public class ErrorMessage : IMessage
{
public string Message { get; set; }
}
// Make a class that implements the ILoggingStrategy interface
// In this instance I want a logging implementation that can log to an xml file
public class XmlFileStrategy : ILoggingStrategy
{
string filePath;
public XmlFileStrategy(string filePath)
{
this.filePath = filePath;
}
public void Perform(IMessage message)
{
if (string.IsNullOrEmpty(filePath))
throw new ApplicationException("FilePath is not set");
XDocument logFile = File.Exists(filePath) ? XDocument.Load(filePath) : CreateLogFile();
logFile.Root.Add(new XElement("Message", message.Message));
logFile.Save(filePath);
}
private static XDocument CreateLogFile()
{
XDocument logFile = new XDocument();
logFile.Declaration = new XDeclaration("1.0", "utf-8", "yes");
XElement root = new XElement("ErrorMessages");
logFile.Add(root);
return logFile;
}
}
// Make a class that implements the ILoggingStrategy interface
// In this instance I want a logging implementation that can log to an MS Sql database
public class MsSqlDbStrategy : ILoggingStrategy
{
string connectionString;
public MsSqlDbStrategy(string connectionString)
{
this.connectionString = connectionString;
}
public void Perform(IMessage message)
{
if (string.IsNullOrEmpty(connectionString))
throw new ApplicationException("ConnectionString is not set");
SqlCommand command = new SqlCommand();
command.CommandType = CommandType.Text;
command.CommandText = "INSERT INTO Errors (Message) VALUES (@Message)";
command.Parameters.Add("Message", SqlDbType.NVarChar).Value = message.Message;
command.Connection = new SqlConnection(connectionString);
command.Connection.Open();
command.ExecuteNonQuery();
command.Connection.Close();
}
}
// Make a class that implements the AbstractLogger abstract class
// This will be your own logger class
public class ErrorLogger : AbstractLogger
{
public ErrorLogger(params ILoggingStrategy[] loggingStrategy) : base(loggingStrategy)
{}
}
That is it! Now you have a tiny logging framework that is easy to extend and easy to use.
09 September 2008
Lightweight Specification using lambda
Using the Specification pattern kan be somewhat cumbersome as the number of specifications increase. You will most certainly want to create so many generic specifications (ie. NonEmptyStringSpecification etc.) as you can and keep the number of specialized specifications to a minimum.
But even then, sometimes you just need to create a quick and dirty specification here and now, not wanting to create a whole class for it. You can ofcause just use a Predicate, but if you want to stay in the world of interfaces, you can use this code:
And if you have a Customer class such as this one:
You can use it like this:
And if you really insist, we could extend it to use the Composite Specification pattern - but I'll leave that as an exercise for you ;)
But even then, sometimes you just need to create a quick and dirty specification here and now, not wanting to create a whole class for it. You can ofcause just use a Predicate, but if you want to stay in the world of interfaces, you can use this code:
8 public interface ISpecification<T>
9 {10 bool IsSatisfiedBy(T candidate);
11 } 12 13 public abstract class AbstractSpecification<T> : ISpecification<T>
14 {15 protected readonly Predicate<T> predicate;
16 17 protected AbstractSpecification(Predicate<T> predicate)
18 {19 this.predicate = predicate;
20 } 21 22 public abstract bool IsSatisfiedBy(T candidate);
23 } 24 25 public class Specification<T> : AbstractSpecification<T>
26 {27 public Specification(Predicate<T> predicate) : base(predicate)
28 { 29 } 30 31 public override bool IsSatisfiedBy(T candidate)
32 {33 return predicate.Invoke(candidate);
34 } 35 }And if you have a Customer class such as this one:
25 public class Customer
26 {27 public string Name { get; set; }
28 public string Address { get; set; }
29 public string Zip { get; set; }
30 public string City { get; set; }
31 public string Phone { get; set; }
32 public string Email { get; set; }
33 public string ContactPerson { get; set; }
34 }You can use it like this:
49 class Program
50 {51 static void Main(string[] args)
52 {53 var customers = new List<Customer>()
54 {55 new Customer() { Name = "Birds and bees", Email = "info@birdsandbees.dk" },
56 new Customer() { Name = "Honey and sugar" },
57 new Customer() { Email = "info@lasttreeonearth.org" }
58 }; 59 60 // A valid customer must have a name and an email
61 var validCustomerSpecification = new Specification<Customer>(c => !string.IsNullOrEmpty(c.Name) && !string.IsNullOrEmpty(c.Email));
62 63 foreach (var customer in customers)
64 {65 if (validCustomerSpecification.IsSatisfiedBy(customer))
66 {67 Console.WriteLine("The valid customers are: " + customer.Name + " (" + customer.Email + ")");
68 }69 else
70 {71 Console.WriteLine("The invalid customers are: " + customer.Name + "( " + customer.Email + ")");
72 } 73 } 74 75 76 Console.ReadKey();
77 } 78 }And if you really insist, we could extend it to use the Composite Specification pattern - but I'll leave that as an exercise for you ;)
Labels: Advanced Programming, C#, Learning
08 September 2008
Composite Specification Pattern
I'm a bit pressed for time, so I'll just dumb the Composite Specification Pattern code here for now and comment it later.
7 public interface ISpecification<T>
8 {9 bool IsSatisfiedBy(T candidate);
10 ISpecification<T> And(ISpecification<T> other);
11 ISpecification<T> Or(ISpecification<T> other);
12 ISpecification<T> Not();
13 } 14 15 public class CompositeSpecification<T> : ISpecification<T>
16 {17 public virtual bool IsSatisfiedBy(T candidate)
18 {19 throw new NotImplementedException();
20 } 21 22 public ISpecification<T> And(ISpecification<T> other)
23 {24 return new AndSpecification<T>(this, other);
25 } 26 27 public ISpecification<T> Or(ISpecification<T> other)
28 {29 return new OrSpecification<T>(this, other);
30 } 31 32 public ISpecification<T> Not()
33 {34 return new NotSpecification<T>(this);
35 } 36 } 37 38 public class AndSpecification<T> : CompositeSpecification<T>
39 {40 private ISpecification<T> one;
41 private ISpecification<T> other;
42 43 public AndSpecification(ISpecification<T> one, ISpecification<T> other)
44 {45 this.one = one;
46 this.other = other;
47 } 48 49 public override bool IsSatisfiedBy(T candidate)
50 {51 return one.IsSatisfiedBy(candidate) && other.IsSatisfiedBy(candidate);
52 } 53 } 54 55 public class OrSpecification<T> : CompositeSpecification<T>
56 {57 private ISpecification<T> one;
58 private ISpecification<T> other;
59 60 public OrSpecification(ISpecification<T> one, ISpecification<T> other)
61 {62 this.one = one;
63 this.other = other;
64 } 65 66 public override bool IsSatisfiedBy(T candidate)
67 {68 return one.IsSatisfiedBy(candidate) || other.IsSatisfiedBy(candidate);
69 } 70 } 71 72 public class NotSpecification<T> : CompositeSpecification<T>
73 {74 private ISpecification<T> wrapped;
75 76 public NotSpecification(ISpecification<T> one)
77 { 78 wrapped = one; 79 } 80 81 public override bool IsSatisfiedBy(T candidate)
82 {83 return !wrapped.IsSatisfiedBy(candidate);
84 } 85 }Labels: Advanced Programming, C#, Patterns
07 September 2008
Specification pattern
Recently I introduced the Strategy pattern to a colleague. He caught on right away and within hours he had refactored a few monster classes to use the Strategy pattern, thereby improving the readability, the maintainability, the seperation of concern and the coherency of his code.
Now this week I'll introduce the Specification pattern to said colleague and see where it takes him :)
In short, the Specification pattern is a pattern for expressing a rule with which you want to test an object. The real power of a Specification is that it separates two distinct concerns; testing objects and the objects themselves.
So here is an example. I'll let the code speak for itself:
And here is how you could put it to use:
This is a very simple example. I'll follow up with a more realistic example and extend the Specification pattern shown here to the much more powerful Composite Specification pattern.
Now this week I'll introduce the Specification pattern to said colleague and see where it takes him :)
In short, the Specification pattern is a pattern for expressing a rule with which you want to test an object. The real power of a Specification is that it separates two distinct concerns; testing objects and the objects themselves.
So here is an example. I'll let the code speak for itself:
8 // The interface that all specifications must implement
9 public interface ISpecification<T>
10 {11 bool IsSatisfiedBy(T entity);
12 } 13 14 // In this example I'll be using two products of different type,
15 // that implement the same interface
16 public interface IProduct
17 {18 string Name { get; set; }
19 decimal Price { get; set; }
20 } 21 22 // The Bicycle class
23 public class Bicycle : IProduct
24 {25 public string Name { get; set; }
26 public decimal Price { get; set; }
27 } 28 29 // The MotorCycle class
30 public class MotorCycle : IProduct
31 {32 public string Name { get; set; }
33 public decimal Price { get; set; }
34 } 35 36 // The BicycleSpecification implements the ISpecification interface
37 // It checks if the type of entity equals the type of the Bicycle class
38 public class BicycleSpecification : ISpecification<IProduct>
39 {40 public bool IsSatisfiedBy(IProduct entity)
41 {42 return entity.GetType() == typeof(Bicycle);
43 } 44 } 45 46 // The MotorcycleSpecification implements the ISpecification interface
47 // It checks if the type of entity equals the type of the MotorCycle class
48 public class MotorcycleSpecification : ISpecification<IProduct>
49 {50 public bool IsSatisfiedBy(IProduct entity)
51 {52 return entity.GetType() == typeof(MotorCycle);
53 } 54 }And here is how you could put it to use:
8 class Program
9 {10 static void Main(string[] args)
11 {12 // Bicycles
13 Bicycle cycle1 = new Bicycle() { Price = 1000, Name = "cycle1" };
14 Bicycle cycle2 = new Bicycle() { Price = 2000, Name = "cycle2" };
15 Bicycle cycle3 = new Bicycle() { Price = 3000, Name = "cycle3" };
16 17 // MotorCycles
18 MotorCycle motorCycle1 = new MotorCycle() { Price = 40000, Name = "motorCycle1" };
19 MotorCycle motorCycle2 = new MotorCycle() { Price = 60000, Name = "motorCycle2" };
20 MotorCycle motorCycle3 = new MotorCycle() { Price = 80000, Name = "motorCycle3" };
21 22 // We add them to a List
23 List<IProduct> allProducts = new List<IProduct>();
24 allProducts.Add(cycle1); 25 allProducts.Add(cycle2); 26 allProducts.Add(cycle3); 27 allProducts.Add(motorCycle1); 28 allProducts.Add(motorCycle2); 29 allProducts.Add(motorCycle3); 30 31 // Instanciating a BicycleSpecification
32 BicycleSpecification cycleSpecification = new BicycleSpecification();
33 // Instanciating a MotorcycleSpecification
34 MotorcycleSpecification motorCycleSpecification = new MotorcycleSpecification();
35 36 // Lets iterate through our List
37 // For each cycle found in the List, we apply the BicycleSpecification to see
38 // if the current cycle satisfies it. If it does, we write its name and price out
39 foreach (var cycle in allProducts)
40 {41 if (cycleSpecification.IsSatisfiedBy(cycle))
42 {43 Console.WriteLine("Price of " + cycle.Name + " is $" + cycle.Price.ToString());
44 } 45 } 46 47 Console.WriteLine();
48 Console.WriteLine();
49 50 // Lets iterate through our List again
51 // For each cycle found in the List, we apply the MotorcycleSpecification to see
52 // if the current cycle satisfies it. If it does, we write its name and price out
53 foreach (var motorCycle in allProducts)
54 {55 if (motorCycleSpecification.IsSatisfiedBy(motorCycle))
56 {57 Console.WriteLine("Price of " + motorCycle.Name + " is $" + motorCycle.Price.ToString());
58 } 59 } 60 61 Console.ReadKey();
62 } 63 }This is a very simple example. I'll follow up with a more realistic example and extend the Specification pattern shown here to the much more powerful Composite Specification pattern.
Labels: Advanced Programming, C#, Code, Learning
14 June 2008
XML Schema validation using LINQ to XML
When you work with XML you will often need to validate it against a Schema document (.xsd). In this example I am creating an XML document (and saving it to disk) by using the XDocument class in combination with a Repository and some nifty LINQ query syntax.
The XML Schema:
The service class with methods to create, validate and save an XDocument:
And lastly how it can be used:
The XML Schema:
1 xml version="1.0" encoding="utf-8"?>
2 <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
3 <xs:element name="registrants">
4 <xs:complexType>
5 <xs:sequence>
6 <xs:element maxOccurs="unbounded" name="registrant">
7 <xs:complexType>
8 <xs:sequence>
9 <xs:element name="name" type="xs:string" />
10 <xs:element name="adress" type="xs:string" />
11 <xs:element name="zip" type="xs:string" />
12 <xs:element name="city" type="xs:string" />
13 <xs:element name="mobilePhone" type="xs:string" />
14 <xs:element name="homePhone" type="xs:string" />
15 <xs:element name="email" type="xs:string" />
16 <xs:element name="activity" type="xs:string" />
17 <xs:element name="comments" type="xs:string" />
18 <xs:element name="updateViaEmail" type="xs:boolean" />
19 xs:sequence>
20 xs:complexType>
21 xs:element>
22 xs:sequence>
23 xs:complexType>
24 xs:element>
25 xs:schema>
The service class with methods to create, validate and save an XDocument:
13 public class RegistrantService
14 {15 private static string websiteRoot = HttpContext.Current.Server.MapPath("~");
16 17 public static XDocument GetAllRegistrants()
18 {19 // TODO: Use IoC container for DataContext in repository
20 var registrantRepository = new Repository<Registrant>(new DataContext());
21 22 var registrants = new XDocument(
23 new XElement("registrants",
24 from r in registrantRepository.All()
25 select new XElement("registrant",
26 new XElement("name", r.Name),
27 new XElement("adress", r.Adress),
28 new XElement("zip", r.Zip),
29 new XElement("city", r.City),
30 new XElement("mobilePhone", r.Mobile),
31 new XElement("homePhone", r.Telephone),
32 new XElement("email", r.Email),
33 new XElement("activity", r.Activity),
34 new XElement("comments", r.Comments),
35 new XElement("updateViaEmail", r.ReceiveNewsletter))));
36 37 return registrants;
38 }39 public static bool IsValid(XDocument document)
40 {41 return IsValid("registrants.xsd", document);
42 }43 public static bool IsValid(string schema, XDocument document)
44 {45 bool isValid = true;
46 XmlSchemaSet registrantsSchemaSet = LoadSchema(schema);
47 //registrants.Validate(registrantsSchemaSet, ValidationEventHandler);
48 document.Validate(registrantsSchemaSet, (s, e) => isValid = false);
49 50 return isValid;
51 }52 private static void ValidationEventHandler(object sender, ValidationEventArgs args)
53 {54 throw new ApplicationException(args.Message);
55 }56 private static XmlSchemaSet LoadSchema(string schema)
57 {58 XmlSchemaSet schemaSet = new XmlSchemaSet(new NameTable());
59 60 using (XmlReader reader = XmlReader.Create(Path.Combine(websiteRoot, schema)))
61 {62 XmlSchema registrantSchema = XmlSchema.Read(reader, null);
63 reader.Close(); 64 65 schemaSet.Add(registrantSchema); 66 } 67 68 return schemaSet;
69 }70 public static void SaveToDisk(XDocument registrants)
71 {72 SaveToDisk("registrants.xml", registrants);
73 }74 public static void SaveToDisk(string fileName, XDocument registrants)
75 {76 string filePath = Path.Combine(websiteRoot, fileName);
77 registrants.Save(filePath); 78 } 79 }And lastly how it can be used:
14 15 XDocument registrants = RegistrantService.GetAllRegistrants();
16 17 if (RegistrantService.IsValid(registrants))
18 RegistrantService.SaveToDisk(registrants);
19 20 // OR using overloaded options
21 22 if (RegistrantService.IsValid("registrants.xsd", registrants))
23 RegistrantService.SaveToDisk("AllRegistrants.xml", registrants);
24 Labels: C#, LINQ, XML Schema
22 May 2008
ImageToBase64Converter class
Update: Refactored the class a bit. Changed "file" to "image" in method names to reduce semantic noise (as "file" is a higher level abstraction than "image"). I removed data URI scheme information from the mimetypes dictionary and placed it in their own methods.
A generic version is on its way...
A generic version is on its way...
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 5 /// <summary>
6 /// Some browsers allow image images to be embedded inline in html documents, Firefox being one of them.
7 /// The image must be converted to base64 encoded characters (or alternatively ASCII encoded characters)
8 /// before being used as embedded content.
9 ///
10 /// This class takes an image and converts it to base64 encoded characters and appends required (by browser)
11 /// mimetype information as well as encoding information to this string, making it usable such as this:
12 ///
13 /// ImageToBase64Converter image = new ImageToBase64Converter();
14 /// myImage.Src = image.ConvertImageToBase64(Server.MapPath("~/images/someImage.jpg"));
15 ///
16 /// The image src attribute contains character info such as this (shortened):
17 ///
18 /// src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAANgAA/+4ADkFkb2JlAGTA
19 /// Af/bAIQABwUFBQYFBwYGBwsHBgcLDAkHBwkMDgwMDAwMDhEMDAwMDAwRDhEREhERDhYWFxcWFiAfHx8gIyMjIyMjIyMjIwEI
20 /// CAgPDQ8cEhIcHhgUGB4jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj/8AAEQgBlQEi
21 /// +jeppi9hFHBJpowJK5grQn4vbTGWC5C1CBr4VJHCtK9+AmE+o5CgBNfHjgirvMwXbL9zmVgk1H/stX88FcctHKKudARm..." />
22 ///
23 /// Read about the 'data: URI scheme' here: http://en.wikipedia.org/wiki/Data:_URI_scheme
24 /// </summary>
25 26 public class ImageToBase64Converter
27 {28 protected IDictionary<string, string> mimeTypes;
29 30 public ImageToBase64Converter(IDictionary<string, string> mimeTypes)
31 {32 this.mimeTypes = mimeTypes;
33 }34 public ImageToBase64Converter()
35 {36 mimeTypes = new Dictionary<string, string>();
37 mimeTypes.Add(".jpeg", "image/jpeg");
38 mimeTypes.Add(".jpg", "image/jpeg");
39 mimeTypes.Add(".gif", "image/gif");
40 mimeTypes.Add(".tif", "image/tiff");
41 mimeTypes.Add(".tiff", "image/tiff");
42 mimeTypes.Add(".bmp", "image/bmp");
43 }44 public virtual string ConvertImageToBase64(string imagePath)
45 {46 string imageExtension = GetImageExtension(imagePath);
47 byte[] imageByteArray = ConvertImageToByteArray(imagePath);
48 char[] imageCharArray = CreateCharArrayFrom(imageByteArray);
49 imageCharArray = ConvertToBase64CharArray(imageByteArray, imageCharArray); 50 51 return string.Format(GetDataURISchemeFormat(), // "data:{0};{1},{2}"
52 GetMimeType(imageExtension), // "image/jpeg"
53 GetEncoding(), // "base64"
54 ConvertCharArrayToString(imageCharArray)); // "/9j/4AAQSkZJRgABAgAAZAB..."
55 }56 protected virtual string GetImageExtension(string imagePath)
57 {58 return Path.GetExtension(imagePath).ToLower();
59 }60 protected virtual string GetMimeType(string imageExtension)
61 {62 if (!mimeTypes.ContainsKey(imageExtension))
63 throw new ApplicationException(string.Format("Image imagetype ({0}) is not supported", imageExtension));
64 65 return mimeTypes[imageExtension];
66 }67 protected virtual byte[] ConvertImageToByteArray(string imagePath)
68 {69 return File.ReadAllBytes(imagePath);
70 }71 protected virtual char[] CreateCharArrayFrom(byte[] imageByteArray)
72 {73 // The size of the char[] must be at least 4/3 the size of the source byte[] and must be divisible by 4,
74 // as each 3 byte sequence in the byte[] becomes a 4 byte sequence in the char[].
75 int length = (int)(Math.Ceiling((double)imageByteArray.Length / 3) * 4);
76 return new char[length];
77 }78 protected virtual char[] ConvertToBase64CharArray(byte[] imageByteArray, char[] imageCharArray)
79 {80 Convert.ToBase64CharArray(imageByteArray, 0, imageByteArray.Length, imageCharArray, 0);
81 return imageCharArray;
82 }83 protected virtual string ConvertCharArrayToString(char[] imageCharArray)
84 {85 return new string(imageCharArray);
86 }87 protected virtual string GetDataURISchemeFormat()
88 {89 // data:[<MIME-type>][;base64],<data>
90 return "data:{0};{1},{2}";
91 }92 protected virtual string GetEncoding()
93 {94 return "base64";
95 } 96 }Labels: C#
14 May 2008
WebConfigManager class v2
By popular demand, here's a more conventional version of a web.config file helper class using inherent BCL classes like:
The class:
And how you use it:
Update: I've added functionality to handle Membership-, Roles- and Profile providers as well as connectionstrings. You can download it here...
- System.Configuration.Configuration
- System.Configuration.WebConfigurationManager
- System.Web.Configuration.MembershipSection
- System.Configuration.ProviderSettings
The class:
10 using System.Web.Configuration;
11 using System.Configuration;
12 13 public static class WebConfigManager
14 {15 public static void SetDefaultMembershipProvider(string name)
16 {17 Configuration webConfig = WebConfigurationManager.OpenWebConfiguration("~");
18 19 if (webConfig.HasFile)
20 {21 MembershipSection membership = webConfig.GetSection("system.web/membership") as MembershipSection;
22 if (membership!=null)
23 { 24 membership.DefaultProvider = name;25 webConfig.Save(ConfigurationSaveMode.Modified);
26 } 27 } 28 }29 public static void AddMembershipProvider(ProviderSettings provider)
30 {31 Configuration webConfig = WebConfigurationManager.OpenWebConfiguration("~");
32 33 if (webConfig.HasFile)
34 {35 MembershipSection membership = webConfig.GetSection("system.web/membership") as MembershipSection;
36 if (membership != null)
37 { 38 membership.Providers.Add(provider);39 webConfig.Save(ConfigurationSaveMode.Modified);
40 } 41 } 42 }43 public static void RemoveMembershipProvider(string name)
44 {45 Configuration webConfig = WebConfigurationManager.OpenWebConfiguration("~");
46 if (webConfig.HasFile)
47 {48 MembershipSection membership = webConfig.GetSection("system.web/membership") as MembershipSection;
49 if (membership != null)
50 { 51 membership.Providers.Remove(name);52 webConfig.Save(ConfigurationSaveMode.Modified);
53 } 54 } 55 } 56 }And how you use it:
19 ProviderSettings provider = new ProviderSettings();
20 provider.Name = "MyProvider";
21 provider.Type = "";
22 provider.Parameters.Add("applicationName", "");
23 provider.Parameters.Add("description", "");
24 provider.Parameters.Add("enablePasswordReset", "");
25 provider.Parameters.Add("enablePasswordRetrieval", "");
26 provider.Parameters.Add("maxInvalidPasswordAttempts", "");
27 provider.Parameters.Add("minRequiredNonAlphanumericCharacters", "");
28 provider.Parameters.Add("minRequiredPasswordLength", "");
29 provider.Parameters.Add("passwordAttemptWindow", "");
30 provider.Parameters.Add("passwordFormat", "");
31 provider.Parameters.Add("passwordStrengthRegularExpression", "");
32 provider.Parameters.Add("requiresQuestionAndAnswer", "");
33 provider.Parameters.Add("requiresUniqueEmail", "");
34 35 WebConfigManager2.AddMembershipProvider(provider);
36 37 WebConfigManager2.SetDefaultMembershipProvider("MyProvider");
38 39 WebConfigManager2.RemoveMembershipProvider("MyProvider");
Update: I've added functionality to handle Membership-, Roles- and Profile providers as well as connectionstrings. You can download it here...
22 July 2007
Playing with anonymous methods and closures in C#
While it may be a bit difficult to read at first, I like the power of anonymous methods and closures in C# - among many cool things, it allows us to do fun stuff like this:
public partial class Calculator : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
OperationDelegate[] calculator = CreateCalculator();
calculator[Arithmetic.Add](2);
calculator[Arithmetic.Subtract](-2);
calculator[Arithmetic.Multiply](2);
decimal result = calculator[Arithmetic.Divide](2);
Response.Write(result);
}
public delegate U OperationDelegate<T,U>(T arg);
public struct Arithmetic
{
public const int Add = 0;
public const int Subtract = 1;
public const int Multiply = 2;
public const int Divide = 3;
}
public OperationDelegate<decimal, decimal>[] CreateCalculator()
{
decimal value = 0; // outer variable binds to 'value' variable in inner function, thus invoking closure
return new OperationDelegate<decimal, decimal>[] {
delegate(decimal number) { value += number; return value; }, // index 0 ~ calculator[Arithmetic.Add]
delegate(decimal number) { value -= number; return value; }, // index 1 ~ calculator[Arithmetic.Subtract]
delegate(decimal number) { value *= number; return value; }, // index 2 ~ calculator[Arithmetic.Multiply]
delegate(decimal number) { value /= number; return value; } // index 3 ~ calculator[Arithmetic.Divide]
};
}
}
Labels: C#
Subscribe to Posts [Atom]

