Pierre Greborio.NET

Talking about .NET world

November 2004 - Posts

Strategy vs Policy pattern

The strategy pattern encapsulates an algorithm inside a class in order to make them interchangable. For example consider we have to round a monetary value to the nearest smallest currency. We could define an interface:

public interface RoundingStrategy
{
  double Round(double amount);
}

and then several strategy algorithms, such as:

public class EurRoundingStrategy : RoundingStrategy
{
  public double Round(double amount)
  {
    // Implementation here
  }
}

and

public class UsdRoundingStrategy : RoundingStrategy
{
  public double Round(double amount)
  {
    // Implementation here
  }
}

But generally, this isn't enought. We have to add other methods that round not only to the smallest currency but also to a user/law/business defined amount, then we can use the policy pattern (a generalization to the strategy pattern) adding new methods:

public interface RoundingStrategy
{
  double Round(double amount);
  double Round(double amount, double precision);
}

gYearMonth - DateTime mapping

gYearMonth represent a date (in a Gregorian calendar) formatted as yyyy-MM (.NET formatting string). In the current (Visual Studio .NET 2003 and 2005 beta) implementations, the gYearMonth type is mapped to System.String.

If you need to map it to a System.DateTime type you have to convert the System.String to System.DateTime throught ParseExact method, or implement your own type as following (please consider that the code isn't fully tested):

[XmlSchemaProvider("gYearMonthSchema")]
public class gYearMonth : IXmlSerializable
{
 private DateTime _value;

 public gYearMonth()
 {
  _value = DateTime.MinValue;
 }

 public gYearMonth(DateTime date)
 {
  _value = date;
 }

 public static implicit operator gYearMonth(DateTime date)
 {
  return new gYearMonth(date);
 }

 public static implicit operator DateTime(gYearMonth date)
 {
  return date._value;
 }

 public static XmlQualifiedName gYearMonthSchema(XmlSchemaSet set)
 {
  XmlQualifiedName n = new XmlQualifiedName("gYearMonth", "
http://www.w3.org/2001/XMLSchema");
  return (n);
 }

 public XmlSchema GetSchema()
 {
  throw new NotImplementedException();
 }

 public void ReadXml(System.Xml.XmlReader reader)
 {
  _value = DateTime.ParseExact(reader.ReadString(), "yyyy-MM", null);
 }

 public void WriteXml(System.Xml.XmlWriter writer)
 {
  writer.WriteString(_value.ToString("yyyy-MM"));
 }
}

The concept is generalizable to all date types.

Posted: Nov 28 2004, 09:48 AM by PierreG | with 1 comment(s)
Filed under:
SOAP faults on WSDL

Soap Faults are an important way to communicate to the consumer (SOAP Node) that something goes wrong.  For each operation we can associate more than one fault message (0..N). Today (and probably on Visual Studio .Net 2005 too) we can't define the soap:fault content (message) to generate into the WSDL document from the code.

I hope (someday) to have some attribute (SoapFaultAttrinbute ?) that permits to define which soap fault to use in some circumstances. Is it a so bad idea ?

Posted: Nov 25 2004, 05:08 PM by PierreG | with 2 comment(s)
Filed under:
Composite key

Two days ago I wrote about the key identity for OO-Table mapping. The sample code works only for a single key field in the table, but it doesn't for a composite key values.

There are several solutions for this problem and probably, the simples one is to create a CompositeKey calss wich is a simple list of Key objects. In order to have a generic container of keys identified by an identifier (field name ?) we have to inherit the Key class from an interface (empty):

public interface IKey { }

public class Key<T> : IKey
{
  // ....
}

Then, the CompositeKey can contains an array of keys as following:

class CompositeKey : Dictionary<string, IKey>
{
    public IKey GetKeyByIdentity(string identifier)
    {
        return this[identifier];
    }

    // ...
}

[Question: can you suggest a better name than identifier ?]

In order to have a more usable container we can add some convenience methods, such as:

public void Add(string identifier, Guid code)
{
    this.Add(identifier, (new Key<Guid>(code)) as IKey);
}

Another idea is to have several Key fields into the domain object.

 

WS-Addressing usage

WS-Addressing is a really nice specification. The only problem is its immatiruty. Just looking to namespaces:

  1. WSE 2.0 uses http://schemas.xmlsoap.org/ws/2004/03/addressing
  2. WS-Addressing core uses http://www.w3.org/2004/10/addressing
  3. WS-Addressing submission uses http://schemas.xmlsoap.org/ws/2004/08/addressing

Ok, that is the price of evolution/standardization. That means, we can't, today, use WS-Addressing for production projects. But for similar issues, do we have to build our own SoapHeader ?

Posted: Nov 23 2004, 03:31 PM by PierreG | with no comments
Filed under:
What future for queues ?

Ok, the asynchronous world is supported today principally by MSMQ. What the future will be ?

  1. MSMQ
  2. Service Broker of MS SQL 2005
  3. Biztalk (MSMQT)

 

Identity field

The identity in object orientation is the memory object address (its pointer). In a database it is the primary key. Martin Fowler suggests to save the identity of the database table (primary key) on the object field/s.

Ok, which key type are we using ? Is it an integer, uniqueidentifier, varchar, char or whatelse ? We can define e generic type mapped to any type we need, more or less as following:

public class Key<T>
{
 private T _value;

 public Key() { }

 public Key(T value)
 {
  if (value == null)
   _value = default(T);
  else
   _value = value;
 }

 public override string ToString()
 {
  return (_value == null) ? "" : _value.ToString();
 }

 public static implicit operator Key<T>(T value)
 {
  return new Key<T>(value);
 }

 public static implicit operator T(Key<T> value)
 {
  if (value == null)
   return default(T);
  else
   return value._value;
 }
}

Obviously, the above type doesn't consider primary keys composed by multiple columns. In that case we could implement an IList<Key> or something like that. 

More Posts