<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Yves Reynhout's Blog</title><link>http://weblogs.asp.net/yreynhout/default.aspx</link><description>The seagile man</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>MVVM Mediator Deluxe</title><link>http://weblogs.asp.net/yreynhout/archive/2009/10/07/mvvm-mediator-deluxe.aspx</link><pubDate>Tue, 06 Oct 2009 23:05:21 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7224405</guid><dc:creator>yreynhout</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=7224405</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=7224405</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2009/10/07/mvvm-mediator-deluxe.aspx#comments</comments><description>&lt;p&gt;From what I’ve &lt;a href="http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx"&gt;been reading&lt;/a&gt; on the implementations of the Mediator pattern for MVVM, I must say I’m a little disappointed. Maybe it’s my background with a certain &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0201342782/"&gt;UI design&lt;/a&gt; methodology (for which I must credit &lt;a href="http://www.linkedin.com/profile?viewProfile=&amp;amp;key=5128808"&gt;Philip Almey&lt;/a&gt;, a former colleague) for the last five or six years. Using (hierarchic) state charts to design user interfaces allows you to think about it’s behavior without being hampered by technology nor content or style. I’m happy that this “way of thinking” still stands firm as technology progresses (into Silverlight/WPF that is). Translating such charts into the asynchronous code flows that rule the “new world” is a challenge. One that requires clear separation of concerns, and the MVVM pattern adds a lot of value to solve this challenge. Another piece of the puzzle is the &lt;a href="http://www.thejoyofcode.com/A_Suck_Less_Event_Aggregator_for_Prism.aspx"&gt;EventAggregator&lt;/a&gt; (&lt;a href="http://www.codeplex.com/prism"&gt;Prism&lt;/a&gt; term) / &lt;a href="http://marlongrech.wordpress.com/2009/04/16/mediator-v2-for-mvvm-wpf-and-silverlight-applications/"&gt;Mediator&lt;/a&gt; / Message Bus / Messenger that provides the communication mechanism between your views and view models. But current implementations seem to focus on using the mediator as a publish/subscribe pattern vehicle and going to great lengths to eliminate memory leaks (which I personally find a little over the top considering that “unsubscribe” should be something explicit).&lt;/p&gt;  &lt;p&gt;Looking at the mediator communication mechanism from a messaging perspective, I see a lot of room for improvement. There is no explicit concept of addressability (think &lt;a href="http://www.w3.org/Submission/ws-addressing/"&gt;WS-Addressing&lt;/a&gt;). If I want to send a message to a specific view, I’ll have to juggle with predicates and properties to make it work. Mind you I’m not advocating for tightly coupling views and view models (although some implementations already do this on subscription ;-)). After all, for addressability, one can simply use &lt;a href="http://msdn.microsoft.com/en-us/library/system.uri.aspx"&gt;System.Uri&lt;/a&gt;. Along with addressability comes explicit support for the request/response message exchange pattern (alongside the existing publish/subscribe pattern). I’d like to see an API along the following lines:&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="550"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="548"&gt;         &lt;p&gt;//Receive any message of the specified type           &lt;br /&gt;IDisposable Accept&amp;lt;TRequest&amp;gt;(RequestCallback&amp;lt;TRequest&amp;gt; callback) where TRequest : RequestMessage;&lt;/p&gt;          &lt;p&gt;//Receive messages of the specified type matching the predicate           &lt;br /&gt;IDisposable Accept&amp;lt;TRequest&amp;gt;(Expression&amp;lt;Predicate&amp;lt;TRequest&amp;gt;&amp;gt; predicate, RequestCallback&amp;lt;TRequest&amp;gt; callback) where TRequest : RequestMessage;&lt;/p&gt;          &lt;p&gt;//Reply to a request message           &lt;br /&gt;void Reply&amp;lt;TReply&amp;gt;(TReply reply) where TReply : ReplyMessage;&lt;/p&gt;          &lt;p&gt;//Send a request message           &lt;br /&gt;void Request&amp;lt;TRequest, TReply&amp;gt;(TRequest request, ReplyCallback&amp;lt;TReply&amp;gt; callback)            &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; where TRequest : RequestMessage            &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; where TReply : ReplyMessage; &lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Remark: People who have used WSE3 (yes, really) will know that you can use the message to specify the addressing bits.&lt;/p&gt;  &lt;p&gt;I know this API is more rigid (contrary to sprinkling Action&amp;lt;T&amp;gt;) but that’s also its strength. It forces you to think in terms of request/reply messages that flow around. This is how I discovered that &lt;a href="http://en.wikipedia.org/wiki/Sequence_diagram"&gt;sequence diagrams&lt;/a&gt; are the new hype all over again to model the communication between views and view models and how they help me understand the message flow. I realize that there are a lot of details and mechanics about the API that I haven’t explained, but this post is just intended to get the juices flowing.&lt;/p&gt;  &lt;p&gt;My conclusion: Is it impossible to achieve the above with the current incarnations? No, but it’s cumbersome and too verbose.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7224405" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/WPF/default.aspx">WPF</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/Mediator/default.aspx">Mediator</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/Silverlight/default.aspx">Silverlight</category></item><item><title>DLinq - First Impression</title><link>http://weblogs.asp.net/yreynhout/archive/2005/09/16/425385.aspx</link><pubDate>Fri, 16 Sep 2005 10:32:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:425385</guid><dc:creator>yreynhout</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=425385</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=425385</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2005/09/16/425385.aspx#comments</comments><description>&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;I thought I'd just have my say about this as these gentlemen already have [ &lt;A href="http://weblogs.asp.net/PWilson"&gt;PeeWeeWilson&lt;/a&gt; &amp;amp; &lt;A href="http://weblogs.asp.net/fbouma"&gt;Fouma&lt;/a&gt; ]. After having read the overview paper (rather diagonal I might add) I can't help but notice the three-way mapping is gone (domain schema &amp;lt;-&amp;gt; mapping schema &amp;lt;-&amp;gt; relational schema), which I find a pitty. From the simplicity point of view I can fully understand why, but believe me when I say that flexibility is sacrificed.&lt;br /&gt; Recently Steve Eichert mentioned using &lt;a href="http://steve.emxsoftware.com/Entity+Framework/If+Attributes+are+good+enough+for+Indigo+why+arent+they+good+enough+for+OR+Mappers"&gt;DataContract&lt;/a&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt; as a way to describe &lt;/font&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;what is persistable and what is not. An interesting idea, but there are too many references to the web service world (Namespace, MustUnderstand, ...). Secondly, if I'd like to expose the class/message using [DataContract] via a web service I wouldn't feel very comfortable with "what is persistable" and "what is part of the message" being the same. Creating a new set of attributes [PersistenceContract], [PersistenceMember(Name=...)] and [PersistenceMemberReference(Name=...)], [PersistenceConstructor] sounds more appealing to me. They could form the domain/persistence schema, which could in turn be consumed by the mapping schema or code which defines the mapping/transformation.&lt;br /&gt; Unlike Paul and Frans, I don't advocate against using attributes. What I do advocate against is the fact that relational concepts such as table, column, native or abstract column types, primary or foreign key and relationship show up in my domain model, and this for the very same reasons as Paul &amp;amp; Frans do (call it one thing in SqlServer, call it another in Oracle; inject some kind of custom transformation in the mapping because there is a mismatch between the CLR type and the native db type). Unfortunately this is exactly what DLinq does. Marketing-wise this could be interpreted as "Let's sell more SQL servers". Opening things up would only allow you to switch to Oracle more easily. Wether that was the reasoning behind this all, I really don't know. Let's just hope that in the future DLinq will embrace flexibility and database independence.&lt;/font&gt;&lt;br /&gt; &lt;font size="2"&gt;&lt;font face="Tahoma"&gt; &lt;a href="http://objectsharp.com/blogs/barry/archive/2005/09/13/3395.aspx"&gt;Resources on Linq&lt;/a&gt;&lt;br /&gt; &lt;/font&gt;&lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=425385" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/Object_2F00_Relational+Mapping/default.aspx">Object/Relational Mapping</category></item><item><title>Computing on demand</title><link>http://weblogs.asp.net/yreynhout/archive/2005/06/02/410167.aspx</link><pubDate>Thu, 02 Jun 2005 18:22:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:410167</guid><dc:creator>yreynhout</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=410167</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=410167</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2005/06/02/410167.aspx#comments</comments><description>&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;An interface I find very useful lately is IComputeOnDemand (although it is highly debatable if it should be an interface at all):&lt;br /&gt; &lt;br /&gt; &lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; /// &lt;font color="#008000"&gt;Behavior for things that can be computed on demand.&lt;/font&gt;&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#0000ff"&gt;public interface&lt;/font&gt; IComputeOnDemand {&lt;br /&gt; &amp;nbsp; &lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &lt;font color="#008000"&gt;Gets a value indicating whether this instance is computed.&lt;/font&gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;value&amp;gt;&lt;br /&gt; &amp;nbsp; /// &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;c&amp;gt;&lt;font color="#008000"&gt;true&lt;/font&gt;&amp;lt;/c&amp;gt; &lt;font color="#008000"&gt;if this instance is computed; otherwise, &lt;/font&gt;&amp;lt;c&amp;gt;&lt;font color="#008000"&gt;false&lt;/font&gt;&amp;lt;/c&amp;gt;.&lt;br /&gt; &amp;nbsp; /// &amp;lt;/value&amp;gt;&lt;/font&gt;&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;bool &lt;/font&gt;IsComputed { &lt;font color="#0000ff"&gt;get&lt;/font&gt;; }&lt;br /&gt; &lt;br /&gt; &amp;nbsp; &lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &lt;font color="#008000"&gt;Gets or sets the inner value.&lt;/font&gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;value&amp;gt;&amp;lt;/value&amp;gt;&lt;/font&gt;&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;object &lt;/font&gt;InnerValue { &lt;font color="#0000ff"&gt;get&lt;/font&gt;; &lt;font color="#0000ff"&gt;set&lt;/font&gt;; }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;font face="Tahoma"&gt;Classes often have properties that only need to be computed once. The most used approach to handle this is by introducing some variable (e.g. loaded, calculated) which indicates if some computation has taken place. An example:&lt;br /&gt; &lt;br /&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;&lt;font face="Courier New"&gt;&lt;font face="Tahoma"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;public class&lt;/font&gt; SomeClass {&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;private bool&lt;/font&gt; loadedField1;&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;private int&lt;/font&gt; field1;&lt;br /&gt; &lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;public int&lt;/font&gt; Field1 {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;get&lt;/font&gt; {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;if&lt;/font&gt; (!&lt;font color="#0000ff"&gt;this&lt;/font&gt;.loadedField1){&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008000"&gt;//Do some "heavy" computation here.&lt;/font&gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;this&lt;/font&gt;.field1 = resultOfComputation;&lt;br /&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;&lt;font face="Courier New"&gt;&lt;font face="Tahoma"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;this&lt;/font&gt;.loadedField1 = true;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;br /&gt; &lt;font size="2"&gt;&lt;font face="Tahoma"&gt;&lt;font face="Courier New"&gt;&lt;font face="Tahoma"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return &lt;/font&gt;this.field1;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &amp;nbsp; }&lt;br /&gt; }&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;&lt;font face="Courier New"&gt;&lt;font face="Tahoma"&gt;&lt;font face="Courier New"&gt;&lt;br /&gt; &lt;br /&gt; &lt;font face="Tahoma"&gt;While this is fine for one field, consider this scenario for multiple fields in one class. Pretty soon the class gets cluttered with these "loaded" fields. But there's even bigger danger lurking: What if you bypass the property and start using the field without it being initialized? Will you ever know? Ofcourse you only get this within the class itself (I'm assuming you've banned the evil called public fields). Let's add a new exception:&lt;br /&gt; &lt;br /&gt; &lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; /// &lt;font color="#008000"&gt;The exception that is thrown when something is not computed.&amp;nbsp;&lt;/font&gt; &lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br /&gt; &lt;font color="#0000ff"&gt;public class&lt;/font&gt; NotComputedException: ApplicationException {&lt;br /&gt; &amp;nbsp; &lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &lt;font color="#008000"&gt;Creates a new &amp;lt;see cref="NotComputedException"/&amp;gt; instance.&lt;/font&gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;public &lt;/font&gt;NotComputedException(): &lt;font color="#0000ff"&gt;base&lt;/font&gt;() {}&lt;br /&gt; &amp;nbsp; &lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &lt;font color="#008000"&gt;Creates a new &amp;lt;see cref="NotComputedException"/&amp;gt; instance.&lt;/font&gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;param name="message"&amp;gt;&lt;font color="#008000"&gt;Message.&lt;/font&gt;&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;public &lt;/font&gt;NotComputedException(&lt;font color="#0000ff"&gt;string &lt;/font&gt;message): &lt;font color="#0000ff"&gt;base&lt;/font&gt;(message) {}&lt;br /&gt; &amp;nbsp; &lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &lt;font color="#008000"&gt;Creates a new &amp;lt;see cref="NotComputedException"/&amp;gt; instance.&lt;/font&gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;param name="message"&amp;gt;&lt;font color="#008000"&gt;Message.&lt;/font&gt;&amp;lt;/param&amp;gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;param name="innerException"&amp;gt;&lt;font color="#008000"&gt;Inner exception.&lt;/font&gt;&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;public &lt;/font&gt;NotComputedException(&lt;font color="#0000ff"&gt;string &lt;/font&gt;message, Exception innerException): &lt;font color="#0000ff"&gt;base&lt;/font&gt;(message, innerException) {}&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;font face="Tahoma"&gt;What's next? Well, time for some &lt;a href="http://www.codesmithtools.com/"&gt;code smitherings&lt;/a&gt;: For each of your &lt;i&gt;compute on demand&lt;/i&gt; data types, you generate a "typed" holder class. I took System.Boolean as an example (mind the "no boxing here"):&lt;br /&gt; &lt;br /&gt; &lt;font face="Courier New"&gt;&lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; /// &lt;font color="#008000"&gt;Represents a placeholder for a &lt;font color="#808080"&gt;&amp;lt;see cref="Boolean"/&amp;gt;&lt;/font&gt; value.&lt;/font&gt;&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &lt;/font&gt;&lt;font color="#0000ff"&gt;public class&lt;/font&gt; BooleanHolder: IComputeOnDemand {&lt;br /&gt; &amp;nbsp; &lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &lt;font color="#008000"&gt;Creates a new &lt;/font&gt;&amp;lt;see cref="BooleanHolder"/&amp;gt;&lt;font color="#008000"&gt; instance.&lt;/font&gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;/font&gt;&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;public &lt;/font&gt;BooleanHolder() {&lt;br /&gt; &amp;nbsp; }&lt;br /&gt; &lt;br /&gt; &amp;nbsp; &lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &lt;font color="#008000"&gt;Creates a new &lt;/font&gt;&amp;lt;see cref="BooleanHolder"/&amp;gt;&lt;font color="#008000"&gt; instance.&lt;/font&gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;param name="innerValue"&amp;gt;Inner value.&amp;lt;/param&amp;gt;&lt;/font&gt;&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;public &lt;/font&gt;BooleanHolder(Boolean innerValue){&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;this&lt;/font&gt;.InnerValue = innerValue;&lt;br /&gt; &amp;nbsp; }&lt;br /&gt; &lt;br /&gt; &amp;nbsp; &lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &lt;font color="#008000"&gt;Gets a value indicating whether this instance is computed.&lt;/font&gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;value&amp;gt;&lt;br /&gt; &amp;nbsp; /// &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;c&amp;gt;&lt;font color="#008000"&gt;true&lt;/font&gt;&amp;lt;/c&amp;gt; &lt;font color="#008000"&gt;if this instance is computed; otherwise,&lt;/font&gt; &amp;lt;c&amp;gt;&lt;font color="#008000"&gt;false&lt;/font&gt;&amp;lt;/c&amp;gt;.&lt;br /&gt; &amp;nbsp; /// &amp;lt;/value&amp;gt;&lt;/font&gt;&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;public bool&lt;/font&gt; IsComputed {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;get &lt;/font&gt;{&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return this&lt;/font&gt;._computed;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &amp;nbsp; }&lt;font color="#0000ff"&gt;bool&lt;/font&gt; _computed = &lt;font color="#0000ff"&gt;false&lt;/font&gt;;&lt;br /&gt; &lt;br /&gt; &amp;nbsp; &lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &lt;font color="#008000"&gt;Gets or sets the inner value.&lt;/font&gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;value&amp;gt;&amp;lt;/value&amp;gt;&lt;/font&gt;&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;public &lt;/font&gt;Boolean InnerValue{&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;get &lt;/font&gt;{&lt;br /&gt; &lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if &lt;/font&gt;(!&lt;font color="#0000ff"&gt;this&lt;/font&gt;.IsComputed) {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;throw new&lt;/font&gt; NotComputedException();&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return this&lt;/font&gt;._innerValue;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;set &lt;/font&gt;{&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;this&lt;/font&gt;._innerValue = value;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;this&lt;/font&gt;.MarkAsComputed();&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &amp;nbsp; }Boolean _innerValue;&lt;br /&gt; &lt;br /&gt; &amp;nbsp;&lt;font color="#808080"&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &lt;font color="#008000"&gt;Gets or sets the inner value.&lt;/font&gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;value&amp;gt;&amp;lt;/value&amp;gt;&lt;/font&gt;&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;object &lt;/font&gt;IComputeOnDemand.InnerValue {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;get &lt;/font&gt;{&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return &lt;/font&gt;this.InnerValue;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;set &lt;/font&gt;{&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;this&lt;/font&gt;.InnerValue = (Boolean)&lt;font color="#0000ff"&gt;value&lt;/font&gt;;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &amp;nbsp; }&lt;br /&gt; &lt;br /&gt; &amp;nbsp; &lt;font color="#808080"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &lt;font color="#008000"&gt;Marks as computed.&lt;/font&gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &amp;nbsp; /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/font&gt;&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;private void&lt;/font&gt; MarkAsComputed(){&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;this&lt;/font&gt;._computed = true;&lt;br /&gt; &amp;nbsp; }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;font face="Tahoma"&gt;Using this approach you get a less cluttered class and a nice exception when using a field that wasn't computed. As noted by &lt;a href="http://johnritsema.com/blog/"&gt;John Ritsema&lt;/a&gt;, in Whidbey generics can be used to simplify things (see &lt;A href="http://weblogs.asp.net/yreynhout/archive/2005/06/02/410167.aspx#410181"&gt;comment&lt;/a&gt; for how-to).&lt;br /&gt; &lt;br /&gt; &lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;public class&lt;/font&gt; SomeClass {&lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;private &lt;/font&gt;BooleanHolder field1;&lt;br /&gt; &lt;br /&gt; &amp;nbsp; &lt;font color="#0000ff"&gt;public bool&lt;/font&gt; Field1 {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;get &lt;/font&gt;{&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;if&lt;/font&gt;(!field1.IsComputed){&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008000"&gt;//Do some "heavy" computation here.&lt;/font&gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;this&lt;/font&gt;.field1.InnerValue = resultOfComputation;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return this&lt;/font&gt;.field1.InnerValue;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &amp;nbsp; }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;font face="Tahoma"&gt;I tend to appreciate the small things in life...&lt;/font&gt;&lt;br /&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=410167" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/Code+generation/default.aspx">Code generation</category></item><item><title>Patents: System.Data.Mapping to resurface?</title><link>http://weblogs.asp.net/yreynhout/archive/2005/05/18/407377.aspx</link><pubDate>Wed, 18 May 2005 18:58:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:407377</guid><dc:creator>yreynhout</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=407377</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=407377</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2005/05/18/407377.aspx#comments</comments><description>&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;What have we &lt;a href="http://www.freshpatents.com/Mapping-architecture-for-arbitrary-data-models-dt20050303ptan20050050068.php"&gt;here&lt;/a&gt;?&lt;br /&gt; &lt;/font&gt;&lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=407377" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/Object_2F00_Relational+Mapping/default.aspx">Object/Relational Mapping</category></item><item><title>Visiting SQL - Update</title><link>http://weblogs.asp.net/yreynhout/archive/2005/04/24/404064.aspx</link><pubDate>Sun, 24 Apr 2005 18:45:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:404064</guid><dc:creator>yreynhout</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=404064</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=404064</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2005/04/24/404064.aspx#comments</comments><description>&lt;font face="Tahoma" size="2"&gt;It seems like I'm not the only one who has been playing with this idea: &lt;a href="http://sourceforge.net/projects/sqlom/"&gt;sqlom&lt;/a&gt;&lt;br /&gt; &lt;/font&gt; &lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=404064" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/Object_2F00_Relational+Mapping/default.aspx">Object/Relational Mapping</category></item><item><title>Visiting SQL - Part 2</title><link>http://weblogs.asp.net/yreynhout/archive/2005/04/12/400042.aspx</link><pubDate>Tue, 12 Apr 2005 21:02:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:400042</guid><dc:creator>yreynhout</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=400042</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=400042</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2005/04/12/400042.aspx#comments</comments><description>&lt;font face="Tahoma" size="2"&gt;In &lt;A href="http://weblogs.asp.net/yreynhout/archive/2005/04/09/397754.aspx"&gt;part 1&lt;/a&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt; I explained how I got a "typed model" of a database schema for building SQL in code. By itself I found this useful, but I still hated the string concatenation involved (not to speak of the scattering of all this string manipulation). So I came up with the idea to build a hand-made object model for all SQL query related objects. This model would allow me to build SQL statements in a typed and database-agnostic fashion, integrating nicely with my typed &lt;i&gt;database schema&lt;/i&gt; model. To give you a rough idea I included some schematics:&lt;br /&gt; &lt;br /&gt; &lt;/font&gt; &lt;div align="center"&gt;&lt;font face="Tahoma" size="2"&gt;- The core interfaces -&lt;/font&gt;&lt;br /&gt; &lt;/div&gt; &lt;div align="center"&gt;&lt;font face="Tahoma" size="2"&gt;&lt;img src="http://users.skynet.be/yreynhout/coreinterfaces.gif" /&gt;&lt;/font&gt;&lt;br /&gt; &lt;font face="Tahoma" size="2"&gt;- The core classes (and some derived ones to give you an idea) -&lt;/font&gt;&lt;br /&gt; &lt;font face="Tahoma" size="2"&gt; &lt;img src="http://users.skynet.be/yreynhout/coreclasses.gif" /&gt; &lt;br /&gt; &lt;/font&gt; &lt;div align="left"&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;&lt;br /&gt; The main interfaces of interest are ISqlSerializable (a.k.a. IVisitable with the accept method replaced with the more appropriate WriteSql) and ISqlWriter (a.k.a. the Visitor). Basically, I've taken the visitor pattern and applied it to writing SQL, allowing for extensibility (&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;for each of the SQL dialects out there) and refraining developers (in theory) from polluting the code with string concatenated SQL. The not so apparent added value is the amount of reuse one can achieve with this type of model (from caching to creating dynamic views).&lt;br /&gt; The only drawback (maybe there are more, but this is the major one) to using an object model is that your SQL becomes very much unreadable as complexity grows. Then again, this may be a sign that you're not doing enough in your domain model or (e.g. for &lt;i&gt;performance, security reasons&lt;/i&gt;) it might be wise to push this logic into a stored procedure. But even this can be solved, by simply modelling each query statement as a class, which can be easily serialized into SQL to see if you get the desired SQL statement (the truly brave might even parse a SQL string and reverse engineer it into the object model).&lt;br /&gt; I think there's enough food for thought in here. Sorry if I haven't gone into too much detail, but a high-level overview is what I had in mind. Feel free to inquire for more.&lt;br /&gt; &lt;/font&gt;&lt;/font&gt;&lt;/div&gt; &lt;font face="Tahoma" size="2"&gt; &lt;/font&gt;&lt;font face="Tahoma" size="2"&gt; &lt;/font&gt;&lt;/div&gt; &lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=400042" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/Object_2F00_Relational+Mapping/default.aspx">Object/Relational Mapping</category></item><item><title>Visiting SQL - Part 1</title><link>http://weblogs.asp.net/yreynhout/archive/2005/04/09/397754.aspx</link><pubDate>Fri, 08 Apr 2005 22:31:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:397754</guid><dc:creator>yreynhout</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=397754</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=397754</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2005/04/09/397754.aspx#comments</comments><description>&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;Apparently, after some months of intensive work, I'm dieing to share (and reflect on) some of the things I've worked on&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;.&lt;br /&gt; &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;&lt;br /&gt; &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;Although "pluggable database backends" and "SQL abstraction" were not directly goals of the project (regular OLTP app), I kind of stumbled on them by accident (just don't call me nuts yet). &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;First off, &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;a lot has already been written about "&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;pluggable database backends", achieved using the IDbXYZ and IDataZYX interfaces which any decent &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconimplementingnetdataprovider.asp"&gt;.NET data provider&lt;/a&gt; implements, so I'm not gonna talk about that.&lt;br /&gt; &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;At work, I tend to use a lot of dynamic SQL because I don't want too much of my &lt;i&gt;business logic&lt;/i&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt; "locked" in&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt; &lt;i&gt;stored procedures&lt;/i&gt;. The whole dynamic SQL versus stored procedures topic is not something I want to delve in now, so we're not gonna talk about that either. Dynamic SQL built in code suffers the problem that as the database schema changes, the "SQL building code" should change along with it. So how do you know which SQL building code is affected by changes in the database schema? If the SQL was somehow typed, the compiler would tell you. Making the SQL typed would mean that there should be some object model in place that, for starters, allows you to represent the database objects (think views, tables, columns, ...).&lt;br /&gt; &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDataDataSetClassTopic.asp"&gt;Datasets&lt;/a&gt;, and in particular the typed flavor, come to mind. But they're a little bloated just to represent a schema &lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;(and probably limited as to the types of database objects they can represent). I had a look at &lt;a href="http://www.ericjsmith.net/codesmith/"&gt;CodeSmith&lt;/a&gt;'s SchemaExplorer (which BTW has a slick object model&lt;/font&gt;&lt;font face="Tahoma" size="2"&gt;) but couldn't use it because it's use was primarly to discover the database schema &lt;i&gt;at runtime&lt;/i&gt;. What I was looking for was a static definition of the database schema in C# code&lt;i&gt; at design time &lt;/i&gt;(which I dubbed RelationalSchema). Although I'm not a big proponent of &lt;a href="http://www.martinfowler.com/bliki/Seedwork.html"&gt;DIY&lt;/a&gt;, I really don't think I had much choice at the time. I borrowed some of SchemaExplorer's object model (in redux I might add), and made it xml serializable using one of those fine &lt;a href="http://msdn.microsoft.com/webservices/building/wse/"&gt;WSE&lt;/a&gt; interfaces, namely &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wseref/html/T_Microsoft_Web_Services2_Xml_IXmlElement_Methods.asp"&gt;IXmlElement&lt;/a&gt;(who said you can't reuse wonderful material).&lt;br /&gt; Now that RelationalSchema was born, containing RelationalSchemaDatabase, RelationalSchemaTable, RelationalSchemaView and RelationSchemaColumn, I used CodeSmith to build a template that generates my xml representation of a relational schema. This way I could have an xml representation of any database schema I liked; just a matter of setting the proper connectionstring. Still, this was just a "generic" representation of a database schema. I still wouldn't detect database schema changes this way. Much like datasets definitions can be used to generate typed datasets, I needed a way to generate a typed relational schema. Again, CodeSmith to the rescue. I made a template which creates a typed object model based on the generic object model.&lt;br /&gt; If I was planning on using the "building SQL using strings" approach than my story would be done here. But it isn't...&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;&lt;br /&gt; &lt;/font&gt;&lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=397754" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/Object_2F00_Relational+Mapping/default.aspx">Object/Relational Mapping</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/Code+generation/default.aspx">Code generation</category></item><item><title>The "facets-enabled" meta model</title><link>http://weblogs.asp.net/yreynhout/archive/2005/04/08/397710.aspx</link><pubDate>Fri, 08 Apr 2005 18:04:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:397710</guid><dc:creator>yreynhout</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=397710</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=397710</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2005/04/08/397710.aspx#comments</comments><description>&lt;font face="Tahoma" size="2"&gt;During the course of my current project at work, I've been trying to come up with a way to describe the meta data of my domain model (which I dubbed the meta model).&amp;nbsp; Because I've taking a rather &lt;a href="http://blogs.msdn.com/lucabol/"&gt;ObjectSpaces&lt;/a&gt;-like approach to object-relational mapping, the domain schema I created seemed like a good place to store the facets of my class members(fields and/or properties). Here's an example of what it looks like&lt;/font&gt;:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;="1.0"&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;="UTF-8"&lt;/span&gt;?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;span class="kwrd"&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DomainSchema&lt;/span&gt; &lt;span class="attr"&gt;AssemblyFullName&lt;/span&gt;&lt;span class="kwrd"&gt;="SomeProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"&lt;/span&gt; &lt;br /&gt;&lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;="http://www.seagile.com/domainschema-1.0/"&lt;/span&gt; &lt;br /&gt;&lt;span class="attr"&gt;xmlns:xsi&lt;/span&gt;&lt;span class="kwrd"&gt;="http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt; &lt;span class="attr"&gt;&lt;br /&gt;xsi:schemaLocation&lt;/span&gt;&lt;span class="kwrd"&gt;="http://www.seagile.com/domainschema-1.0/&lt;br /&gt;D:\WorkSpace\SomeProject\trunk\Schemas\DomainSchema.xsd"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Classes&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Class&lt;/span&gt; &lt;span class="attr"&gt;FullName&lt;/span&gt;&lt;span class="kwrd"&gt;="Seagile.SomeProject.SomeBaseClass"&lt;/span&gt; &lt;span class="attr"&gt;IdentityMember&lt;/span&gt;&lt;span class="kwrd"&gt;="ID"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Members&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Member&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="ID"&lt;/span&gt; &lt;span class="attr"&gt;Field&lt;/span&gt;&lt;span class="kwrd"&gt;="_id"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="System.Guid"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Members&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Class&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Class&lt;/span&gt; &lt;span class="attr"&gt;FullName&lt;/span&gt;&lt;span class="kwrd"&gt;="Seagile.SomeProject.SomeClass"&lt;/span&gt; &lt;span class="attr"&gt;BaseClass&lt;/span&gt;&lt;span class="kwrd"&gt;="Seagile.SomeProject.SomeBaseClass"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Members&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Member&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Name"&lt;/span&gt; &lt;span class="attr"&gt;Field&lt;/span&gt;&lt;span class="kwrd"&gt;="_name"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="System.String"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Facets&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MinLength&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;1&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;MinLength&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;5&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Facets&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Member&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Member&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="ExternalCode"&lt;/span&gt; &lt;span class="attr"&gt;Property&lt;/span&gt;&lt;span class="kwrd"&gt;="ExternalCode"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="System.String"&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="attr"&gt;Required&lt;/span&gt;&lt;span class="kwrd"&gt;="False"&lt;/span&gt; &lt;span class="attr"&gt;Default&lt;/span&gt;&lt;span class="kwrd"&gt;="MCQ000"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Facets&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;FixedLength&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;6&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;FixedLength&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Pattern&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;^MCQ\d{3}$&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Pattern&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Facets&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Member&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RelationshipMember&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Category"&lt;/span&gt; &lt;span class="attr"&gt;Field&lt;/span&gt;&lt;span class="kwrd"&gt;="_category"&lt;/span&gt; &lt;span class="attr"&gt;RelationshipType&lt;/span&gt;&lt;span class="kwrd"&gt;="One"&lt;/span&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="attr"&gt;TargetClass&lt;/span&gt;&lt;span class="kwrd"&gt;="Seagile.SomeProject.SomeOtherClass"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RelationshipMember&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Materials"&lt;/span&gt; &lt;span class="attr"&gt;Field&lt;/span&gt;&lt;span class="kwrd"&gt;="_materials"&lt;/span&gt; &lt;span class="attr"&gt;RelationshipType&lt;/span&gt;&lt;span class="kwrd"&gt;="Many"&lt;/span&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="attr"&gt;TargetClass&lt;/span&gt;&lt;span class="kwrd"&gt;="Seagile.SomeProject.Material"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Members&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Class&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Class&lt;/span&gt; &lt;span class="attr"&gt;FullName&lt;/span&gt;&lt;span class="kwrd"&gt;="Seagile.SomeProject.Material"&lt;/span&gt; &lt;span class="attr"&gt;BaseClass&lt;/span&gt;&lt;span class="kwrd"&gt;="Seagile.SomeProject.SomeBaseClass"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Members&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Member&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Name"&lt;/span&gt; &lt;span class="attr"&gt;Field&lt;/span&gt;&lt;span class="kwrd"&gt;="_name"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="System.String"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Member&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="TotalParts"&lt;/span&gt; &lt;span class="attr"&gt;Field&lt;/span&gt;&lt;span class="kwrd"&gt;="_totalParts"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="System.Int32"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Facets&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MinInclusive&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;2&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;MinInclusive&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MaxExclusive&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;11&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;MaxExclusive&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Facets&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Member&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Member&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="BarCode"&lt;/span&gt; &lt;span class="attr"&gt;Field&lt;/span&gt;&lt;span class="kwrd"&gt;="_barCode"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="Seagile.SomeOtherProject.BarCode, SomeOtherProject"&lt;/span&gt; &lt;span class="attr"&gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="attr"&gt;TypeConverter&lt;/span&gt;&lt;span class="kwrd"&gt;="Seagile.SomeOtherProject.Data.BarCodeConverter, SomeOtherProject.Data"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Members&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Class&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Classes&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;DomainSchema&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;B&lt;/font&gt;&lt;font face="Tahoma"&gt;y itself the schema is worth nothing, but in conjunction with a mapping and relational schema it's "easy" for a generic mapping layer to interpret how to retrieve and store objects. Strictly speaking the mapping layer doesn't need the type information and facets. But their presence is very much appreciated by the domain, application and presentation layers. The presentation layer can use the information to constrain the input fields, and both the domain and application layer can feed these facet values to validators (LengthValidator, RegularExpressionValidator, Int32RangeValidator, ...).&lt;br /&gt; The xml representation is both a blessing and a curse. On one side, it's very easy to get up and running (using an xml schema to drive the intellisense and validation). It feels like a modelling tool if the schema is what you start out with. If the domain model is already in place it's a pesky task. Maintenance wise, however, it's a little devil. Having a validator to compare the declarative xml representation against an assembly is not a luxury. Keeping the code and xml in sync is asking for trouble. I think the best way to handle this is (a) to forget this whole idea, (b) have the xml representation generate the code or (c) have the code generate (attribute-based approach) the xml representation.&lt;br /&gt; But lets not forget the problem I'm trying to solve, namely preventing the scattering of the domain's meta data. Where do you store the fact a column is 5 long, how do you constrain the textbox representing that same conceptual value to only take 5 characters to have an overal nice end-user experience, and how about duplicating that value once more in the domain layer so that other "clients" of your code play by the rules? How do you deal with change and know where to look if 5 becomes 10?&lt;br /&gt; &lt;/font&gt;&lt;/font&gt; &lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=397710" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/Object_2F00_Relational+Mapping/default.aspx">Object/Relational Mapping</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/Code+generation/default.aspx">Code generation</category></item><item><title>Collection classes and behavior</title><link>http://weblogs.asp.net/yreynhout/archive/2005/04/05/397114.aspx</link><pubDate>Mon, 04 Apr 2005 22:03:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:397114</guid><dc:creator>yreynhout</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=397114</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=397114</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2005/04/05/397114.aspx#comments</comments><description>&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;Lately I've come up with a technique to implement custom finders/queries/filters on my collection classes. Instead of implementing these &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;finders/queries/filters&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt; directly in the collection class itself, which gets in the way of generating these types of classes anyway (for the record, I am aware of techniques like &lt;a href="http://www.ericjsmith.com/codesmith/"&gt;CodeSmith&lt;/a&gt;'s merge regions), I defined a set of new behaviors:&lt;br /&gt;&lt;font color="#008000" face="Courier New"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt; /// Behavior for things that can be evaluated.&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt;&lt;font color="#0000ff"&gt; public interface &lt;font color="#000000"&gt;IPredicate &lt;/font&gt;{&lt;/font&gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// Evaluates the specified obj.&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="obj"&amp;gt;Object to be evaluated.&amp;lt;/param&amp;gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&amp;gt;&amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; if obj meets the predicate; otherwise &amp;lt;c&amp;gt;false&amp;lt;/c&amp;gt;.&amp;lt;/returns&amp;gt;&lt;br /&gt;&lt;font color="#0000ff"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; bool &lt;font color="#000000"&gt;Evaluate&lt;/font&gt;(object &lt;font color="#000000"&gt;obj&lt;/font&gt;);&lt;br /&gt; }&lt;/font&gt;&lt;br /&gt; &lt;br /&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt; /// Behavior for collections from which items can be extracted using the given &amp;lt;see cref="IPredicate"/&amp;gt;.&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt;&lt;font color="#0000ff"&gt; public interface &lt;font color="#000000"&gt;IExtractable &lt;/font&gt;{&lt;/font&gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Extracts the items from the collection given the specified predicate, leaving only the items that didn't meet the predicate.&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="predicate"&amp;gt;Predicate used to evaluate items against.&amp;lt;/param&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;&lt;font color="#008000" face="Courier New"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&amp;gt;A collection of items that meet the given predicate.&amp;lt;/returns&amp;gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;br /&gt; &lt;font size="2"&gt;&lt;font face="Tahoma"&gt;&lt;font color="#008000" face="Courier New"&gt; &amp;nbsp;&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp; object &lt;font color="#000000"&gt;Extract&lt;/font&gt;(IPredicate &lt;font color="#000000"&gt;predicate&lt;/font&gt;);&lt;br /&gt; }&lt;/font&gt;&lt;br /&gt; &lt;br /&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt; /// Behavior for collections that can be filtered using a given &amp;lt;see cref="IPredicate"/&amp;gt;.&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt;&lt;font color="#0000ff"&gt; public interface &lt;font color="#000000"&gt;IFilterable &lt;/font&gt;{&lt;/font&gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Filters the items in the collection given the specified predicate, effectively removing the items that match the predicate.&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="predicate"&amp;gt;Predicate used to evaluate items against.&amp;lt;/param&amp;gt;&lt;br /&gt;&lt;font color="#0000ff"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; void &lt;font color="#000000"&gt;Filter&lt;/font&gt;(IPredicate &lt;font color="#000000"&gt;predicate&lt;/font&gt;);&lt;br /&gt; }&lt;/font&gt;&lt;br /&gt; &lt;br /&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt; /// Behavior for collections from which items can be selected using the given &amp;lt;see cref="IPredicate"/&amp;gt;.&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt;&lt;font color="#0000ff"&gt; public interface &lt;font color="#000000"&gt;ISelectable &lt;/font&gt;{&lt;/font&gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// Selects the items in the collection given the specified predicate but leaves all items in the collection.&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="predicate"&amp;gt;Predicate used to evaluate items against.&amp;lt;/param&amp;gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&amp;gt;A collection of items that meet the given predicate.&amp;lt;/returns&amp;gt;&lt;br /&gt;&lt;font color="#0000ff"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; object &lt;font color="#000000"&gt;Select&lt;/font&gt;(IPredicate &lt;font color="#000000"&gt;predicate&lt;/font&gt;);&lt;br /&gt; }&lt;br /&gt; &lt;font color="#000000"&gt;&lt;font face="Tahoma"&gt;Next I implemented the ISelectable, IExtractable, IFilterable in my collection class template (regardless of the templating mechanism you use). I even provided typed implementations of these methods (using explicit interface declaration).&lt;br /&gt; Foreach rule/condition I've come across in code, I've created a class implementing IPredicate. Feeding instances of my predicate classes to my collection classes allows me to perform either select, extract or filter operations on them. I've even taking this a step further and implemented a CompoundPredicate which basically is a collection of predicates and a predicate decision combinator (IPredicateDecisionCombinator). When a compound condition is passed to one of the select/extract/filter methods, multiple conditions are evaluated at once and the way the result of these evaluations are combined is the concern of the predicate decision combinator (so you can vary from the simple boolean and/or).&lt;br /&gt; There's some room for improvement, namely the Select and Extract could return ICollection or IList instead of object, but that's a matter of taste to me.&lt;br /&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color="#000000" face="Tahoma"&gt;The beauty of this solution is that the condition (predicate) is totally separate from the function &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;&lt;font color="#008000" face="Courier New"&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000" face="Tahoma"&gt;(extracting, filtering, selecting) &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Tahoma"&gt;&lt;font color="#008000" face="Courier New"&gt;&lt;font color="#0000ff"&gt;&lt;font color="#000000" face="Tahoma"&gt;I want to perform on the collection. Conceptually it is quite similar to Predicate&amp;lt;T&amp;gt; in .NET 2.0 or to IComparer and the Sort method in .NET 1.1 and to some extent to closures. Ofcourse in 1.1 it requires a little more work on your behalf, namely passing around contextual data via the constructor of the predicate whereas in 2.0 anonymous methods will do most of the lifting for you.&lt;/font&gt;&lt;br /&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=397114" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/Code+generation/default.aspx">Code generation</category></item><item><title>SCC in Microsoft Visual Studio.NET 2002/2003: The good, the bad and the ugly</title><link>http://weblogs.asp.net/yreynhout/archive/2004/10/06/238832.aspx</link><pubDate>Wed, 06 Oct 2004 19:45:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:238832</guid><dc:creator>yreynhout</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=238832</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=238832</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2004/10/06/238832.aspx#comments</comments><description>&lt;font face="Verdana" size="2"&gt;GrantRi &lt;A href="http://weblogs.asp.net/grantri/archive/2004/10/06/238716.aspx"&gt;inquires&lt;/a&gt; about what type of SCC the hobbyist programmer uses. I was going to write a comment, but decided to rant about what has been annoying me with SCC in VS.NET 2K2/3.&lt;br /&gt; &lt;br /&gt; &lt;/font&gt;&lt;font face="Verdana" size="2"&gt;There are several reasons not to use the standard scc integration. For one, all this source control information is persisted inside the solution and/or project files. If you have ever tried to branch a solution, you will know what I mean. If you open the solution, you will notice that it is "bound" to the source control location it was originally branched from. To "bind" to the new location, you can use the "Change Source Control" functionality of VS.NET. In some cases you may want to get rid of this source control information. In that case you have to use the "unbind" functionality in VS.NET or alternatively alter the solution and/or project files by stripping the source control information. Secondly, the solution load time is increased if you use the SCC integration. Thirdly, if you use web projects and want to use your main development and branch versions concurrently, you're in for a big mess (although this statement also applies to other source control systems).&lt;br /&gt; The only positive thing about the source control integration is that using "Open from Source Control" a solution is "gotten" automagically (provided you accept that web projects are "gotten" to your local &lt;a href="file://%5C%5C127.0.0.1%5Cwwwroot$"&gt;wwwroot&lt;/a&gt; ).&lt;br /&gt; &lt;/font&gt;&lt;font face="Verdana" size="2"&gt;&lt;br /&gt; For those who want to use the standard SCC integration in VS.NET with other sourcecontrol systems, you can use:&lt;br /&gt; Working with CVS: &lt;/font&gt;&lt;font face="Verdana"&gt;&lt;a href="http://www.pushok.com/soft_cvs.php"&gt;&lt;font size="2"&gt;http://www.pushok.com/soft_cvs.php&lt;/font&gt;&lt;/a&gt;&lt;br /&gt; &lt;/font&gt; &lt;font face="Tahoma" size="2"&gt;&lt;font face="Verdana"&gt;Working with SVN: &lt;a href="http://www.pushok.com/soft_svn.php"&gt;http://www.pushok.com/soft_svn.php&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; Personally, I'm leaning towards &lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt;(Server), &lt;a href="http://tortoisesvn.tigris.org/"&gt;TortoiseSVN&lt;/a&gt;(Client) and &lt;a href="http://ankhsvn.tigris.org/"&gt;ANKH&lt;/a&gt;(IDE Integration).&lt;/font&gt; &lt;br /&gt; &lt;/font&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=238832" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/.NET/default.aspx">.NET</category></item><item><title>WSE 2.0 Extensibility: From spec to code</title><link>http://weblogs.asp.net/yreynhout/archive/2004/06/28/167394.aspx</link><pubDate>Sun, 27 Jun 2004 22:03:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:167394</guid><dc:creator>yreynhout</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=167394</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=167394</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2004/06/28/167394.aspx#comments</comments><description>&lt;p&gt;&lt;font face="Verdana" size="2"&gt;I've started work on a&lt;/font&gt; &lt;a href="http://msdn.microsoft.com/webservices/understanding/specs/default.aspx?pull=/library/en-us/dnglobspec/html/wsrmspecindex.asp" ?&gt;&lt;font face="Verdana" size="2"&gt;WS-ReliableMessaging&lt;/font&gt;&lt;/a&gt; &lt;font face="Verdana" size="2"&gt;implementation over at&lt;/font&gt; &lt;a href="http://www.gotdotnet.com/Community/Workspaces/Workspace.aspx?id=b700af79-5b27-4d71-bfbd-8df74fa68abe" ?&gt;&lt;font face="Verdana" size="2"&gt;Plumbwork.Orange&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt;. Although I haven't made any serious advances (usability wise), it already shows that&lt;/font&gt; &lt;a href="http://msdn.microsoft.com/webservices/building/wse/"&gt;&lt;font face="Verdana" size="2"&gt;WSE 2.0&lt;/font&gt;&lt;/a&gt; &lt;font face="Verdana" size="2"&gt;extensibility model is awesome! If you plan on writing an implementation of a spec yourself on top of &lt;a href="http://msdn.microsoft.com/webservices/building/wse/"&gt;WSE 2.0&lt;/a&gt;, dig in using &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector&lt;/a&gt; or fetch a fresh copy of the&lt;/font&gt; &lt;a href="http://www.gotdotnet.com/Community/Workspaces/Workspace.aspx?id=b700af79-5b27-4d71-bfbd-8df74fa68abe" ?&gt;&lt;font face="Verdana" size="2"&gt;Plumbwork.Orange&lt;/font&gt;&lt;/a&gt; &lt;font face="Verdana" size="2"&gt;source.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Verdana" size="2"&gt;So, how's the code organized? You have a WS&amp;lt;spec&amp;gt;.cs containing all the string identifiers (namespace, actions, element names and attribute names) relating to the spec. This class has a real "add code as we go" feeling to it. Next up are the elements and their associated attributes described in the spec. Basically you need to provide an object model, and write the serialization &amp;amp; deserialization code for each element. The namespace in&lt;/font&gt; &lt;a href="http://msdn.microsoft.com/library/en-us/wseref/html/N_Microsoft_Web_Services2_Xml.asp"&gt;&lt;font face="Verdana" size="2"&gt;Microsoft.Web.Services2.Xml&lt;/font&gt;&lt;/a&gt; &lt;font face="Verdana" size="2"&gt;will provide usefull services in this area. Carefully examine the spec to see if you need to derive from&lt;/font&gt; &lt;a href="http://msdn.microsoft.com/library/en-us/wseref/html/T_Microsoft_Web_Services2_Xml_OpenElement.asp"&gt;&lt;font face="Verdana" size="2"&gt;OpenElement&lt;/font&gt;&lt;/a&gt; &lt;font face="Verdana" size="2"&gt;(allowing any (elements) and @any (attributes)) or&lt;/font&gt; &lt;a href="http://msdn.microsoft.com/library/en-us/wseref/html/T_Microsoft_Web_Services2_Xml_OpenElementElement.asp"&gt;&lt;font face="Verdana" size="2"&gt;OpenElementElement&lt;/font&gt;&lt;/a&gt; &lt;font face="Verdana" size="2"&gt;(allowing only any (elements)). The structure of these element classes smells like what xsd.exe /c would generate for you (instead of attributes, think deriviation and add the implementation of an IXmlSerializable look-a-like). If the spec exposes service methods, then add a &amp;lt;spec&amp;gt;Service class (as you would implement a regular webservice using&lt;/font&gt; &lt;a href="http://msdn.microsoft.com/webservices/building/wse/"&gt;&lt;font face="Verdana" size="2"&gt;WSE 2.0&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt;) and provide the implementation for those methods using the element classes you've created. If the spec requires the use of custom headers, derive from &lt;/font&gt;&lt;a href="http://msdn.microsoft.com/library/en-us/wseref/html/T_Microsoft_Web_Services2_SoapInputFilter.asp"&gt;&lt;font face="Verdana" size="2"&gt;SoapInputFilter&lt;/font&gt;&lt;/a&gt; &lt;font face="Verdana" size="2"&gt;and&lt;/font&gt; &lt;a href="http://msdn.microsoft.com/library/en-us/wseref/html/T_Microsoft_Web_Services2_SoapOutputFilter.asp"&gt;&lt;font face="Verdana" size="2"&gt;SoapOutputFilter&lt;/font&gt;&lt;/a&gt; &lt;font face="Verdana" size="2"&gt;(found in&lt;/font&gt; &lt;a href="http://msdn.microsoft.com/library/en-us/wseref/html/N_Microsoft_Web_Services2.asp"&gt;&lt;font face="Verdana" size="2"&gt;Microsoft.Web.Services2&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt;) and handle the headers (again) using the element classes.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Verdana" size="2"&gt;In a follow-up post I'll discuss where soap faults and policies go...&lt;/font&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=167394" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/yreynhout/archive/tags/SOA/default.aspx">SOA</category></item><item><title>From the trenches: WseWsdl2.exe</title><link>http://weblogs.asp.net/yreynhout/archive/2004/06/04/148055.aspx</link><pubDate>Thu, 03 Jun 2004 23:15:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:148055</guid><dc:creator>yreynhout</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=148055</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=148055</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2004/06/04/148055.aspx#comments</comments><description>&lt;p&gt;&lt;font face="Verdana" size="2"&gt;&lt;font color="#ff0000"&gt;This post has been deprecated by WSE 2.0 SP1 (they've added the "name" commandline parameter to wsewsdl2.exe).&lt;br /&gt; &lt;br /&gt; &lt;/font&gt;&lt;/font&gt;&lt;font face="Verdana" size="2"&gt;"This &lt;/font&gt;&lt;a href="ms-help://MS.WSE20.1033/wse/html/gxaconWSDLToSoapClientTool.htm%27" target="_blank"&gt;&lt;font face="Verdana" size="2"&gt;WSDL to SoapClient tool&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt; generates proxy code for Web service clients from WSDL files."&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Verdana" size="2"&gt;The documentation states you can retrieve the WSDL via soap.tcp: &lt;br /&gt;"Soap.tcp locations will be retrieved with a SOAP message ("GetDescription")." &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Well, the documentation is not correct. First of all its not &lt;em&gt;GetDescription&lt;/em&gt; but &lt;em&gt;RequestDescription&lt;/em&gt;. Second, you need to inherit from SoapService in order to get the &lt;em&gt;RequestDescription&lt;/em&gt; out-of-the-box. The GetDescription method exists in the SoapReceiver class and by default returns null.&amp;nbsp; So if you happen to inherit from SoapReceiver(which BTW SoapService inherits from), you can provide an implementation for SoapReceiver.GetDescription. But this buys you nothing. You need to provide a method with a&amp;nbsp;SoapMethodAttribute which has a value of SoapReceiver.RequestDescriptionAction (== "&lt;font color="#800000"&gt;&lt;a href="http://schemas.microsoft.com/wse/2003/06/RequestDescription"&gt;http://schemas.microsoft.com/wse/2003/06/RequestDescription&lt;/a&gt;&lt;/font&gt;").&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Verdana" size="2"&gt;Nevertheless, I did not get it to work properly (the proxy generation using soap.tcp that is). I kept on getting "Microsoft.Web.Services2.Addressing.AddressingFault: Destination Unreachable". On the net I found one &lt;/font&gt;&lt;a href="http://msdn.microsoft.com/newsgroups/default.aspx?dg=microsoft.public.dotnet.framework.webservices.enhancements&amp;amp;tid=abf8611d-2f46-4eca-80ce-ca591ab05ad6&amp;amp;lang=en&amp;amp;cr=US&amp;amp;p=1&amp;amp;shell=/newsgroups/configuration.xml" target="_blank"&gt;&lt;font face="Verdana" size="2"&gt;other place&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt; where this was mentioned, but no reply. The funny thing is, that if I requested the description using a self-fabricated class inheriting from SoapClient and defined the RequestDescription method using the proper SoapMethod attribute, I got the WSDL back. So I started digging a little using &lt;/font&gt;&lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;&lt;font face="Verdana" size="2"&gt;Reflector&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt; and came to the conclusion that there was&amp;nbsp;only one main difference between WseWsdl2 and my custom implementation. I used an &lt;em&gt;EndPointReference&lt;/em&gt; with both an &lt;em&gt;Address&lt;/em&gt; and a &lt;em&gt;Via &lt;/em&gt;to initialize SoapClient, whereas WseWsdl2 used the constructor of &lt;em&gt;EndPointReference&lt;/em&gt; specifying only the &lt;em&gt;Address&lt;/em&gt;. So I changed my code to use the same constructor, and low and behold, I got the same error.&amp;nbsp; &lt;font color="#ff0000"&gt;If &lt;em&gt;address&lt;/em&gt; (specified on the SoapService itself via the SoapActor attribute) and &lt;em&gt;via&lt;/em&gt; are the same, WseWsdl2 should work over soap.tcp!&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Verdana" size="2"&gt;I whipped up a &lt;/font&gt;&lt;a href="http://users.skynet.be/yreynhout/SoapTcpWsdl.zip"&gt;&lt;font face="Verdana" size="2"&gt;little tool&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana" size="2"&gt; to call the soap.tcp RequestDescription method using the proper EndPointReference constructor.&lt;br /&gt;Usage: &lt;font color="#ff0000" face="Verdana" size="2"&gt;soaptcpwsdl&lt;/font&gt; /address:&amp;lt;uri&amp;gt; /via:&amp;lt;uri&amp;gt; /output:&amp;lt;wsdl file&amp;gt;&lt;br /&gt;You can use WseWsdl2 on the wsdl output to generate the proxy class.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#ff0000" face="Verdana" size="2"&gt;UPDATE: Seems like I'm not&amp;nbsp;the only one experimenting&amp;nbsp;[&lt;A href="http://weblogs.asp.net/gsusx/archive/2004/06/08/151351.aspx"&gt;http://weblogs.asp.net/gsusx/archive/2004/06/08/151351.aspx&lt;/a&gt;]&lt;/font&gt;&lt;br /&gt;&lt;font ace="Verdana" color="#ff0000" size="2"&gt;UPDATE: Aaron Skonnard points out&amp;nbsp;the use of WseWsdl2&amp;nbsp;[&lt;a href="http://www.pluralsight.com/aaron/default.aspx?key=2004-06-04T21:48:22Z"&gt;http://www.pluralsight.com/aaron/default.aspx?key=2004-06-04T21:48:22Z&lt;/a&gt;]&lt;/font&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=148055" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/SOA/default.aspx">SOA</category></item><item><title>WSE 2.0 Guts</title><link>http://weblogs.asp.net/yreynhout/archive/2004/06/02/146134.aspx</link><pubDate>Tue, 01 Jun 2004 23:25:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:146134</guid><dc:creator>yreynhout</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=146134</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=146134</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2004/06/02/146134.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Verdana size=2&gt;For the last couple of days I have been stairing&amp;nbsp;at the inner workings of &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/webservices/building/wse/default.aspx"&gt;&lt;FONT face=Verdana size=2&gt;WSE 2.0&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt; (using &lt;/FONT&gt;&lt;A href="http://www.aisto.com/roeder/dotnet/"&gt;&lt;FONT face=Verdana size=2&gt;that well known tool&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt;) and I must say it's a fine piece of craftmanship. My focus has been on the Microsoft.Web.Services2.Messaging namespace, which provides the infrastructure (at long last) to host&amp;nbsp;a soap server in your own application (without reverting to ASP.NET runtime hosting). It takes a while to&amp;nbsp;wrap your head around the&amp;nbsp;workflow because I've never seen that many asynchronous methods used together. It is a good example of how to use delegates, asynccallbacks, waithandles, ... to provide a&amp;nbsp;scalable messaging solution.&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT face=Verdana size=2&gt;WaitHandleAsyncResult (found in Microsoft.Web.Services2) was a new concept to me. Basically an IAsyncResult implementation that doesn't fire an AsyncCallback until a WaitHandle is signalled. Very powerfull for multi-threaded communication and &lt;EM&gt;it's public&lt;/EM&gt;(better rebuild it yourself in case&amp;nbsp;they pull it from WSE 3.0). Too bad these kind of &lt;EM&gt;patterns&lt;/EM&gt; don't get more attention. Another nice example (although hidden from the public eye) is Microsoft.Web.Services2.Messaging.SoapClient+SoapClientAsyncResult which shows you how to asynchronously send a soap request and on send completion, sit around and wait for the&amp;nbsp;response to get back (again, asynchronously).&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT face=Verdana size=2&gt;When building your own transport, beware to derive your custom Soap&amp;lt;transport&amp;gt;InputChannel from SoapInputChannel, unless you plan to rewrite SoapTransport.DispatchMessage. An interface-based contract would have done the trick&amp;nbsp;here, but I must agree that it probably would have confused the&amp;nbsp;custom transport developer.&amp;nbsp;SoapInputChannel internally uses a System.Collections.Queue to buffer messages and SoapTransport.DispatchMessage puts them into the buffer.&amp;nbsp;&lt;/FONT&gt;&lt;FONT style="TEXT-DECORATION: line-through" face=Verdana size=2&gt;Also note that you can't configure your custom&amp;nbsp;transport (and thus scheme)&amp;nbsp;using the configuration file. You must do this in code (or write your own config section handler which does the lifting)&lt;/FONT&gt;.&amp;nbsp;&lt;FONT face=Verdana size=2&gt;For some reason, the folks implementing the SoapTcpTransport where not happy using the Begin/EndAccept&amp;nbsp;members of a socket, and implemented a windows socket event sink. They must have had their reason for doing this ... wonder what it could be.&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT face=Verdana size=2&gt;All in all a nice release ... one we can learn from.&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color=#ff0000&gt;UPDATE: &lt;FONT color=#000000&gt;Steve Main shows us how to configure your custom transport (scheme) using the configuration file [&lt;/FONT&gt;&lt;A href="http://hyperthink.net/blog/Trackback,guid,6f17e650-f077-4479-9cd0-0a40baf5463b.aspx" target=_blank&gt;Permalink&lt;/A&gt;&lt;/FONT&gt;]&lt;/P&gt;&lt;P&gt;&lt;FONT color=#ff0000&gt;UPDATE II: &lt;/FONT&gt;After doing some more digging (actually stairing at same code over and over again) I finally found what I had been misinterpreting. If you specify a type attribute on the &amp;lt;messaging&amp;gt;&amp;lt;transports&amp;gt;&amp;lt;add&amp;gt; tag, another branch of the code is executed which does the transport type loading.&lt;/P&gt;&lt;P&gt;So to conclude,&lt;/P&gt;&lt;P&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;messaging&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;transports&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;add&lt;/SPAN&gt; &lt;SPAN style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;scheme&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;="[Out-of-the-box transport scheme]"&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;transports&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;messaging&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;or&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;messaging&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;transports&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;add&lt;/SPAN&gt; &lt;SPAN style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;scheme&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;="[Custom transport scheme]"&lt;/SPAN&gt; &lt;SPAN style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;type&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;="[Custom transport type]"&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;transports&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: maroon; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;messaging&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=146134" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/SOA/default.aspx">SOA</category></item><item><title>SOA and the domain model</title><link>http://weblogs.asp.net/yreynhout/archive/2004/03/07/85604.aspx</link><pubDate>Sun, 07 Mar 2004 22:14:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:85604</guid><dc:creator>yreynhout</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=85604</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=85604</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2004/03/07/85604.aspx#comments</comments><description>&lt;P&gt;&lt;A href="http://weblogs.asp.net/fbouma/archive/2004/03/06/85105.aspx"&gt;Frans Bouma&lt;/A&gt;&amp;nbsp;touches&amp;nbsp;the architectural topic of object-message mapping (or what Martin Fowler calls Data Transfer Object).&lt;/P&gt;&lt;P&gt;Do we need an domain model when working in a SOA (a.k.a. the moving target of today) environment and hence a way to map SOA's message oriented nature onto the object oriented nature of the domain model? I think it's a matter of context, complexity, personal architectural liking&amp;nbsp;and who was there first, namely the chicken(SOA)&amp;nbsp;or the egg(domain model)?&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Context&lt;/STRONG&gt;:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;What's a service?&lt;/LI&gt;&lt;LI&gt;How do you envision your services?&lt;/LI&gt;&lt;LI&gt;Who will be the consumer of your services and to what end/purpose will they be consumed/used for?&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;STRONG&gt;Complexity:&lt;/STRONG&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;How complex will the logic behind your service to be?&lt;/LI&gt;&lt;LI&gt;Exactly how coarse-grained are they (your services)&amp;nbsp;going to be?&lt;/LI&gt;&lt;LI&gt;Are you going to reuse the logic inside your service (e.g. in another service)?&lt;/LI&gt;&lt;LI&gt;Are you going to reuse that logic&amp;nbsp;in a non-SOA environment?&lt;/LI&gt;&lt;LI&gt;Will a domain model allow you to better understand and maintain your logic?&lt;/LI&gt;&lt;LI&gt;What's the added value of having a domain model behind your service?&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;STRONG&gt;Personal Architectural Liking:&lt;/STRONG&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;How did you develop services before the SOA hype?&lt;/LI&gt;&lt;LI&gt;Is a service an orchestration of cooperating domain objects or an orchestration of other services and messages, to you?&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=85604" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/yreynhout/archive/tags/SOA/default.aspx">SOA</category></item><item><title>Do Da Unit Testing Database</title><link>http://weblogs.asp.net/yreynhout/archive/2004/03/02/82923.aspx</link><pubDate>Tue, 02 Mar 2004 22:41:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:82923</guid><dc:creator>yreynhout</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/rsscomments.aspx?PostID=82923</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/yreynhout/commentapi.aspx?PostID=82923</wfw:comment><comments>http://weblogs.asp.net/yreynhout/archive/2004/03/02/82923.aspx#comments</comments><description>&lt;P&gt;When working with &lt;A href="http://www.martinfowler.com/ap2/timeNarrative.html"&gt;temporal data&lt;/A&gt;&amp;nbsp;stored in an RDBMS it can be tricky to do proper unit testing (actually it's nearly impossible). Essentially, to be able to re-run unit tests you need to be able to restore&amp;nbsp;&lt;EM&gt;time&lt;/EM&gt; and &lt;EM&gt;space&lt;/EM&gt; like it was&amp;nbsp;the previous run. A technique I found usefull was&amp;nbsp;explicitly setting the system time&amp;nbsp;before starting the actual test (PInvoking a Win32 API). After the test had run, I'd just sync up with the domain controller using &lt;STRONG&gt;&lt;EM&gt;net time&lt;/EM&gt;&lt;/STRONG&gt;. Ofcourse, it's never going to be 100% the same, but for most non-real-time systems this will do.&lt;/P&gt;&lt;P&gt;A common problem when doing unit testing is &lt;EM&gt;restoring&lt;/EM&gt; a database(SQL2K) &lt;EM&gt;reliably&lt;/EM&gt; to a known state.&amp;nbsp;The good news is that it's quiet simple (and compared to database recreation via scripts, very fast)!&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;FONT face=Arial&gt;Make sure your database has it's &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/createdb/cm_8_des_03_6ohf.asp"&gt;&lt;FONT face=Arial&gt;AUTO_CLOSE&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Arial&gt;&amp;nbsp;option set. Detach it and remember where that .mdf is located!&lt;/FONT&gt;&lt;/LI&gt;&lt;LI&gt;&lt;FONT face=Arial&gt;The &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDataSqlClientSqlConnectionClassConnectionStringTopic.asp"&gt;&lt;FONT face=Arial&gt;connection string&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Arial&gt; used by your DAL or ObjRelMapper should look like: "Data Source=(local);Initial Catalog=MyDataBase;&lt;FONT color=#ff00ff&gt;&lt;FONT color=#ff0000&gt;AttachDBFilename=D:\MyDataBase.mdf;Pooling=false&lt;/FONT&gt;&lt;FONT color=#000000&gt;;Integrated Security=true;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/LI&gt;&lt;UL&gt;&lt;LI&gt;&lt;FONT face=Arial&gt;AttachDBFilename points to the detached database(a copy would even be better).&lt;/FONT&gt;&lt;/LI&gt;&lt;LI&gt;&lt;FONT face=Arial&gt;Pooling=false ensures you will be able to detach the database later on (should we want to) and that you can re-run the unit tests without exiting the test environment.&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;LI&gt;&lt;FONT face=Arial&gt;If you want to detach your database, use a connection string which connects to the master database and&amp;nbsp;do an &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_sp_da-di_83fm.asp"&gt;&lt;FONT face=Arial&gt;sp_detach_db&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Arial&gt;&amp;nbsp;of your test database. This will allow you to move the .mdf around.&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=82923" width="1" height="1"&gt;</description></item></channel></rss>