tag:blogger.com,1999:blog-201960102024-03-07T05:04:34.533+01:00Frederik Gheysels' DevLogWeblog on C# and software developmentFrederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.comBlogger80125tag:blogger.com,1999:blog-20196010.post-2918632054434991092009-06-19T10:18:00.002+02:002009-06-19T10:44:22.900+02:00WinForms: DataBinding on a cancellable Dialog Form<p>On some occasions, you might want to create a dialog window that enables a user to modify data.</p><p>In almost all situations, you will want to make use of the databinding capabilities in the .NET Framework, so that you do not have to write the tedious synchronization-code yourself.</p><p>However, when you want to databind a custom object to the controls on the dialog-form, databinding might get in the way:<br />When you change the Text in a TextBox that is databound on a property of your object, the property of your object will be updated as soon as the databound TextBox has been validated (default behaviour).<br />This is not a problem, until the user decides that he does not want to keep the changes he has made, and clicks the Cancel button of the dialog form. <br />In such a case, you want to revert back to the original state of the object.</p><p>There are several solutions to handle this problem. <br /><br />One solution is to implement some kind of <a href="http://fgheysels.blogspot.com/2006/01/business-objects-framework-part-1_08.html">Undo-behaviour</a> in your custom object, but this might be a little bit overkill for the situation at hand.</p><p>A more simple solution, is to disable the 2-way databinding when the form is displayed, and explicitly update the databound object when the user clicks the Ok button of the dialog.<br/><br />This can be done like this:</p><pre class="code">public class MyEditForm : Form<br />{<br /> public MyEditForm( MyClass objectToDisplay )<br /> {<br /> // Suppose that you have defined databindings via the<br /> // designer<br /> this.MyBindingSource.DataSource = objectToDisplay;<br /><br /> DataBindingUtils.SuspendTwoWayBinding(this.BindingContext[MyBindingSource]);<br /> }<br /><br /> public void btnOk_Click( object sender, EventArgs e )<br /> {<br /> DataBindingUtils.UpdateDataBoundObject(this.BindingContext[MyBindingSource]);<br /> this.DialogResult = DialogResult.Ok;<br /> }<br /><br /> public void btnCancel_Click( object sender, EventArgs e )<br /> {<br /> this.DialogResult = DialogResult.Cancel;<br /> }<br />}</pre><p>The concept is very simple; when the form is displayed, we suspend the databindings, so that changes that are made to the controls on the form, are not directly persisted in the underlying object.<br />When the user confirms the changes he has made by clicking the OK-button, we need to make sure that the contents of the controls are persisted in the underlying object.</p><p>The two methods that are of interest look like this:</p><pre class="code">public static class DataBindingUtils<br />{<br /> public static void SuspendTwoWayBinding( BindingManagerBase bindingManager )<br /> {<br /> if( bindingManager == null )<br /> {<br /> throw new ArgumentNullException ("bindingManager");<br /> }<br /><br /> foreach( Binding b in bindingManager.Bindings )<br /> {<br /> b.DataSourceUpdateMode = DataSourceUpdateMode.Never;<br /> }<br /> }<br /><br /> public static void UpdateDataBoundObject( BindingManagerBase bindingManager )<br /> {<br /> if( bindingManager == null )<br /> {<br /> throw new ArgumentNullException ("bindingManager");<br /> }<br /><br /> foreach( Binding b in bindingManager.Bindings )<br /> {<br /> b.WriteValue ();<br /> }<br /> }<br />}</pre>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com3tag:blogger.com,1999:blog-20196010.post-9664066465741842932009-05-15T11:49:00.004+02:002009-05-15T12:30:07.889+02:00Forcing NHibernate to cascade deletes before updates<p>At work, I've ran into a particular problem; let me describe the situation at hand.</p><p>Suppose I have the following DB schema:</p><br /><div style="text-align:center"><img src="http://users.pandora.be/fgzone/blog/nhibcascade/db_schema.jpg" /><br /></div><br /><p>In the <code>OrderLines</code> table, there exists a UNIQUE CONSTRAINT on ( OrderId, SequenceNumber)</p><p>Next to this DB schema, I have an <code>Order</code> and an <code>OrderLine</code> class. <br />The <code>Order</code> class has a collection of <code>OrderLines</code>:</p><pre class="code-content"><br />public class Order<br />{<br /> public int Id<br /> {<br /> get;<br /> private set;<br /> }<br /><br /> public ISet<OrderLine> OrderLines = new HashedSet<OrderLine>();<br /><br /> public void AddOrderLine( OrderLine ol )<br /> {<br /> ol.Order = this;<br /> OrderLines.Add (ol);<br /> }<br />}<br /></pre><p>I've them mapped using NHibernate so that I can save them in the above DB schema.<br />In the mapping, I've specified that the OrderLines collection should be cascaded when the Order is saved:</p><pre class="code-content"><br /><set name="OrderLines" cascade="all-delete-orphan"><br /> <key column="OrderId" /><br /> <one-to-many class="OrderLine" /><br /></set><br /></pre><p>Now, all goes well until you remove an OrderLine, add a new OrderLine with the same sequencenumber as the one that you've just removed.</p><p>Instead of first removing the OrderLine that you want to remove, and inserting the new OrderLine afterwards, NHibernate will perform these actions just the other way around:<br /><br />It will first try to insert the new OrderLine, and then it will remove the existing Orderline. <br />Now, since we have a unique constraint in the DB, this will fail offcourse.</p><p>I've found a way to work around this problem. Although I find it not optimal (rather an ugly hack), it kinda works, so I'll stick with it for now.<br />This is how I've done it:</p><ul><br /><li>Instead of specifying 'all-delete-orphan' as the cascade option for the collection, I've modified it to 'delete-orphan' instead. <br />This means that deletes will be cascaded, but inserts & updates are not</li><br /><li>All DB access goes through 'repositories' in my application. This means I have an <code>OrderRepository</code> which has a Save method.<br />I have modified my <code>Save</code> method so it looks like this:<br /><pre class="code-content"><br />public void Save( Order o )<br />{<br /> // With.Transaction only starts a transaction when the given session<br /> // is not in a transaction yet.<br /> // session is an ISession and is a member variable of my Repository.<br /> With.Transaction (session, new delegate()<br /> {<br /> session.SaveOrUpdate (o);<br /><br /> session.Flush();<br /><br /> foreach( OrderLine ol in o.OrderLines ) <br /> {<br /> session.SaveOrUpdate (ol);<br /> }<br /> };<br />}<br /></pre>What I do here, is just calling <code>SaveOrUpdate</code> on the given <code>Order</code>. Because of the cascading setting, only the <code>OrderLines</code> that are to be deleted, will be cascaded.<br />Afterwards, I call the <code>Flush</code> method of the session to make sure that the DELETE statements are actually send to the database.<br /><br />We're now left with the <code>OrderLine</code> entities that are new or modified. To make sure that they get persisted as well, I loop over the <code>OrderLines</code> collection and call SaveOrUpdate for every <code>OrderLine</code> instance.<br />This will make sure that new <code>OrderLines</code> get inserted and modified ones, are updated. <br />NHibernate will not update those <code>OrderLines</code> that are not changed.</li></ul><br /><br />Although this 'hack' is nicely hidden / abstracted by the Repository, I still find it a bit ugly, but at this very moment I see no better way to handle this kind of issue ...Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com2tag:blogger.com,1999:blog-20196010.post-12006555613375194532008-09-02T21:42:00.002+02:002008-09-02T21:45:36.370+02:00Google ChromeThe beta-version of Google's Chrome browser is available for <a href="http://www.google.com/chrome/index.html?hl=nl&brand=CHMG&utm_source=nl-hpp&utm_medium=hpp&utm_campaign=nl">download</a>. I've just installed it, and I like it. <br />I love their new 'start-page' concept, for instance.<br /><br />They've also created a <a href="http://www.google.com/chrome/index.html?hl=nl&brand=CHMG&utm_source=nl-hpp&utm_medium=hpp&utm_campaign=nl">comic</a> where they explain the concepts and techniques of Chrome. Very interesting as well. :)Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com0tag:blogger.com,1999:blog-20196010.post-88921307665086276952008-08-25T21:23:00.004+02:002008-08-26T21:59:06.599+02:00On reading books ....<p>Davy Brion has made a <a href="http://davybrion.com/blog/2008/08/software-development-books-investing-in-yourself/">statement</a> on his blogs in where he states that reading certain development books should be considered as an investment for a software developer.</p><p>I fully support that statement.<br />I have a few books on my shelf that I consider as 'my Software Development Bibles'. These books have -imho- sharpened my skills, broadened my view and helped me to be a better developer.<br />These books -which I consider to be my bibles- are, in no particular order:</p><ul><li><a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215">Domain Driven Design: Tackling Complexity in the Heart of Software</a></li><br /><li><a href="http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1219692863&sr=8-1">Design Patterns: Elements of Reusable Object-Oriented Software</a></li><a href="http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1219692863&sr=8-1"><br /></a><li><a href="http://www.amazon.com/Enterprise-Application-Architecture-Addison-Wesley-Signature/dp/0321127420/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1219692907&sr=1-1">Patters of Enterprise Application Architecture</a></li><br /><li><a href="http://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Technology/dp/0201485672/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1219692950&sr=1-1">Refactoring: Improving the design of existing code</a></li><br /><li><a href="http://www.amazon.com/Design-Patterns-Explained-Perspective-Object-Oriented/dp/0321247140/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1219692983&sr=1-1">Design Patterns Explained</a></li><br /><li><a href="http://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1219693145&sr=1-1">Agile Software Development</a></li></ul><br /><p>There are lots of other books on software development on my shelf, but I consider the ones above as the ones that have influenced me most.<br />Books, you can't get enough of them (you still have to read them as well offcourse). There are still some books regarding software-development on my <a href="http://www.amazon.com/gp/registry/registry.html?ie=UTF8&type=wishlist&id=34KVAI4BDKYYU">whishlist</a>, and I'm sure that every now and then, another book will be added to it...</p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com2tag:blogger.com,1999:blog-20196010.post-50077985902415396582008-08-19T21:14:00.014+02:002008-08-25T21:45:34.162+02:00Locking system with aspect oriented programming<h2>Intro</h2><p>A few months ago, I had to implement a 'locking system' at work. <br />I will not elaborate to much on this system, but it's intention is that users can prevent that certain properties of certain entities are updated automatically;<br />The software-system in where I had to implement this functionality, keeps a large database up-to-date by processing and importing lots of data-files that we receive from external sources.<br />Because of that, in certain circumstances, users want to avoid that data that they've manually changed or corrected, gets overwritten with wrong information next time a file is processed.<p><p>The application where I'm talking about, makes heavy use of DataSets and I've been able to create a rather elegant solution for it.<br />At the same time, I've also been thinking on how I could solve this same problem in a system that is built around <a href="http://en.wikipedia.org/wiki/POCO">POCO's</a> instead of Datasets, and that's what this post will be all about. :)</p><h2>Enter Aspects</h2><p>When the idea of implementing such a system first crossed my mind, I already realized that Aspects Oriented Programming could be very helpfull to solve this problem.</p><p>A while ago, I already <a href="http://fgheysels.blogspot.com/2006/11/aspect-oriented-programming-in-net.html">played</a> with Aspect Oriented Programming using Spring.NET. <br />AOP was very nice and interesing, but I found the runtime-weaving a big drawback. Making use of runtime weaving meant that you could not directly create an instance using it's constructor.<br /><br />So, instead of:<pre class='code-content'>MyClass c = new MyClass();</pre>you had to instantiate instances via a proxyfactory:<pre class='code-content'>ProxyFactory f = new ProxyFactory (new TestClass());<br /><br />f.AddAdvice (new MethodInvocationLoggingAdvice());<br /><br />ITest t = (ITest)f.GetProxy();</pre></p><p>I am sure that you agree that this is quite a hassle, just to create a simple instance. (Yes, I know, offcourse you can make abstraction of this by making use of a Factory...).</p><p>Recently however, I bumped at an article on <a href="http://patrickdeboeck.blogspot.com/">Patrick De Boeck's weblog</a>, where he was talking about <a href="http://www.postsharp.org/">PostSharp</a>.<br />PostSharp is an aspect weaver for .NET which weaves at compile-time!<br />This means that the drawback that I just described when you make use of runtime-weaving has disappeared. <br />So, I no longer had excuses to start implementing a similar locking system for POCO's.</p><h2>Bring it on</h2><p>I like the idea of <a href="http://en.wikipedia.org/wiki/Test-driven_development">Test-Driven-Development</a>, so I started out with writing a first simple test:</p><img src="http://users.pandora.be/fgzone/blog/lockingsystem/firsttest.PNG" /><p>The advantage of writing your test first, is that you start thinking on how the interface of our class should look like.</p><p>This first test tells us that our class should have a <code>Lock</code> and an <code>IsLocked</code> method.<br />The purpose of the <code>Lock</code> method is to put a 'lock' on a certain property, so that we can avoid that this property is modified at run-time.<br />The <code>IsLocked</code> method is there to inform us whether a property is locked or not.</p><p>To define this contract, I've created an interface <code>ILockable</code> which contains these 2 methods. <br />In order to get this first test working, I've created an abstract class <code>LockableEntity</code> which inherits from one of my base entity-classes implements this interface.<br />This <code>LockableEntity</code> class looks like this:</p><img src="http://users.pandora.be/fgzone/blog/lockingsystem/firstlockableentity.PNG" /><br /><p>This is not sufficient to get a green bar on my first test, since I still need an <code>AuditablePerson</code> class:</p><img src="http://users.pandora.be/fgzone/blog/lockingsystem/auditpersonforfirsttest.PNG" /><p>These pieces of code are sufficient to make my first test pass, so I continued with writing a second test:</p><img src="http://users.pandora.be/fgzone/blog/lockingsystem/secondtest.PNG" /><p>As you can see, in this test-case I define that it should be possible to unlock a property. Unlocking a property means that the value of that property can be modified by the user at runtime.<br />To implement this simple functionality, it was sufficient to just add an <code>UnLock</code> method to the <code>LockableEntity</code> class:</p><img src="http://users.pandora.be/fgzone/blog/lockingsystem/unlockable.PNG" />.<p>Simple, but now, a more challenging feature is coming up.<br /><br />Now, we can already 'lock' and 'unlock' properties, but there is nothing that really prevents us from changing a locked property.<br />It's about time to tackle this problem and therefore, I've written the following test:</p><img src="http://users.pandora.be/fgzone/blog/lockingsystem/thirdtest.PNG" /><p>Running this test obviously gives a red bar, since we haven't implemented any logic yet.<br />The most simple way to implement this functionality, would be to check in the setter of the <code>Name</code> property whether there exists a lock on this property or not. <br />If a lock exists, we should not change the value of the property, otherwise we allow the change. <br />I think that this is a fine opportunity to use aspects.</p><h3>Creating the Lockable Aspect</h3><p>As I've mentionned earlier, I have used <a href="http://www.postsharp.org/">PostSharp</a> to create the aspects. Once you've downloaded and installed PostSharp, you can create an aspect rather easy.</p><p>There is plenty of <a href="http://www.postsharp.org/about/documentation/">documentation to be found on the PostSharp site</a>, so I'm not going to elaborate here on the 'getting started' aspect (no pun intended).</p><p>Instead, I'll directly dive into the <code>Lockable</code> aspect that I've created.<br /><br />This is how the definition of the class that defines the aspect looks like:</p><img src="http://users.pandora.be/fgzone/blog/lockingsystem/lockaspectdef.PNG" /><p>Perhaps I should first elaborate a bit on how I would like to use this <code>Lockable</code> aspect.<br /><br />I'd like to be able to decorate the properties of a class that should be 'lockable' with an attribute. Like this:</p><img src="http://users.pandora.be/fgzone/blog/lockingsystem/lockableperson.PNG" /><p>Decorating a property with the <code>Lockable</code> attribute, means that the user should be able to 'lock' this property. That is, prevent that it gets changed after it has been locked.<br />To be able to implement this, I've created a class which inherits from the OnMethodInvocationAspect class (which eventually inherits from <code>Attribute</code>).</p><p>Why did I choose this class to inherit from? <br />Well, because there exists no <code>OnPropertyInvocation</code> class or whatsoever.<br /><br />As you probably know, the getters and setters of a property are actually implemented as <code>get_</code> and <code>set_</code> methods, so it is perfectly possible to use the <code>OnMethodInvocationAspect</code> class to add extra 'concerns' to the property.</p><p>This extra functionality is written in the <code>OnInvocation</code> method that I've overriden in the <code>LockableAttribute</code> class.<br /><br />In fact, it does nothing more then checking whether we're in the setter method of the property, and if we are, check whether there exists a lock on the property.<br />If there exists a lock, we won't allow the property-value to be changed. Otherwise, we just make sure that the implementation of the property itself is called.<br />The implementation looks like this:</p><img src="http://users.pandora.be/fgzone/blog/lockingsystem/oninvocation.PNG" /><p>Here, you can see that we use reflection to determine whether we're in the setter-method or in the getter-method of the property; we're only interested if this property is locked if we're about to change the value of the property.</p><p>Next, we need to get the name of the property for which we're entering the setter method. This is done via the <code>GetPropertyForSetterMethod</code> method which uses reflection as well to get the <code>PropertyInfo</code> object for the given setter-method.</p><p>Once this has been done, I can use the <code>IsLocked</code> method to check whether this property is locked or not.<br /><br />Note that I haven't checked whether the conversion from <code>eventArgs.Delegate.Target</code> to <code>ILockable</code> has succeeded or not. More on that later ...</p><p>When the property is locked, I call the <code>OnAttemptToModifyLockedProperty</code> method (which is declared in <code>ILockable</code>), and which just raises the <code>LockedPropertyChangeAttempt</code> event (also declared in the <code>ILockable</code> interface). By doing so, the programmer can decide what should happen when someone / something attempts to change a locked property. This gives a bit more control to the programmer and is much more flexible then throwing an exception.</p><p>When the property is not locked, we let the setter-method execute.</p><p>With the creation of this aspect, our third test finally gives a green bar.</p><h3>Compile time Validation</h3><p>As I've said a bit earlier, I haven't checked in the <code>OnInvocation</code> method whether the Target really implemented the <code>ILockable</code> interface before I called methods of the <code>ILockable</code> type.</p><p>The reason for this , is quite simple: the <code>OnMethodInvocationAspect</code> class has a method <code>CompileTimeValidate</code> which you can override to add compile-time validation logic (hm, obvious).</p><p>I made use of this to check whether the types where I've applied the <code>Lockable</code> attribute really are <code>ILockable</code> types:</p><img src="http://users.pandora.be/fgzone/blog/lockingsystem/compiletimevalidate.PNG" /><br /><small>Note that it should be possible to make this code more concise, but I could not just call <code>method.DeclaringType.GetInterface("ILockable")</code> since that gave a <code>NotImplementedException</code> while compiling. Strange, but true</small><p>Now, when I use the <code>Lockable</code> attribute on a type which is not <code>ILockable</code>, I'll get the following compiler errors:</p><img src="http://users.pandora.be/fgzone/blog/lockingsystem/compileerror.PNG" /><p>Pretty neat, huh ?<br />Now, what's left is a way to persist the locks in a datastore, but that will be a story for some other time ... </p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com2tag:blogger.com,1999:blog-20196010.post-7728173368856472812008-07-28T21:39:00.003+02:002008-07-28T22:48:58.488+02:00NHibernate in a remoting / WCF scenarioI am thinking on how I could use NHibernate in a remoting scenario (using <a href="http://en.wikipedia.org/wiki/.NET_Remoting">.NET remoting</a>, webservices, <a href="http://en.wikipedia.org/wiki/Windows_Communication_Foundation">WCF</a> ... ), but I can already see some problems which I will likely encounter on my path.<br /><br />This is how I see the big picture of the application:<br /><br /><img src="http://users.pandora.be/fgzone/blog/nhibremoting/bigpict.PNG" /><br /><br />Let me explain it in short:<br />The client application (a rich Windows client for instance) communicates via some kind of technique, be it WCF or the old .NET remoting, with the Service Layer.<br />This means that the client application calls a (remote) method on the Service Layer to retrieve a Customer for instance. The client can make some changes to that object and later, the client can call the remote 'SaveCustomer' method so that the Service Layer can persist the changes back to the datastore.<br />In order to do this, the Service Layer uses a Repository that uses NHibernate to retrieve or persist objects.<br />Note that the Client Application and the Remote service layer use the same Domain Entities. This means that the domain classes need to be [Serializable].<br /><br />The problem that I will be facing is this:<br />- Since (N)Hibernate uses its ISession as a UnitOfWork, which keeps track of the objects that have been created, deleted, inserted, the Client Application doesn't know whether it is necessary to perform a remote call to save the entity or not.<br />(The client application doesn't know anything of some thing called an 'NHibernate Session', and my business object (entity) has no state tracking as well. (In other words: my entity itself doesn't know whether it has been created, changed or deleted).<br /><br />- The remote method which will save my entity, will use another ISession then the method that has retrieved it. (Remote methods should be stateless, since multiple callers can call the same method. Client x should not know anything of client Y).<br />The fact that the 'SaveCustomer' method will use another ISession, means that it is possible that NHibernate will perform unnecessary UPDATE statements. This could be problematic if you use an <a href="http://fgheysels.blogspot.com/2008/07/nhibernate-iinterceptor.html">AuditInterceptor</a>, since this Interceptor will update the LastUpdated, Version, etc... columns in the DB, while this was not necessary. In other words: this leads to wrong information in the database.<br /><br />How could these problems be tackled:<br />- For the first problem, you could implement some kind of 'state tracking' in your entities, and add a property which tells you whether the entity has modified , etc...<br /><br />- Implementing state-tracking in your domain entities may also solve the 2nd problem; in your repository you can check whether you've to Update or Save (for new entities) your entity. However, I don't know yet how this will behave in situations where an entity contains a collection of other entities ...<br /><br /><br />I'd like to know from other people how they have tackled these kind of problems ? Did you implement some kind of state tracking in your business entities ? <br />Or, did you choose not to expose your business entities to the client application, and use Data Transfer Objects instead ? If so, how did you map these DTO's to your business classes ?Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com6tag:blogger.com,1999:blog-20196010.post-84947605398500049372008-07-05T20:51:00.007+02:002008-07-05T21:53:16.703+02:00NHibernate IInterceptor: an AuditInterceptor<p>As I was playing around with NHibernate today, I came accross a rather inconvenient problem. :).<br /><br />Let me first explain what I wanted to achieve:<br />For every domain object that I save, I want to persist in the database when the entity has been created, when it has been last updated and by whom. Nothing special, just regular audit-information.<br /><br />To make this all possible, I've created the following classes / interfaces:</p><ul><li><h3><code>IAuditable</code> interface</h3><br /><img src="http://users.pandora.be/fgzone/blog/nhibintercept/iauditable.PNG" /><br /><br /><li><h3><code>AuditableEntity</code> interface</h3><br /><img src="http://users.pandora.be/fgzone/blog/nhibintercept/auditableentity.PNG" /><br /></ul><p>I think this is pretty straightforward and doesn't require any further explanation.<br />Then, I continued with creating an NHibernate interceptor which would set the Created and Updated dates. (I could also used the <code>ILifecycle</code> interface instead, but this meant that I would have a dependency to the NHibernate assembly in my 'domain classes assembly', and I don't like that. In fact, the <code>ILifecycle</code> interface has been deprecated for exactly that reason).<br /><br />This is an extract from my <code>AuditInterceptor</code> which would perform the task I wanted (at least, I thought so ... ).<br />(Note that my <code>AuditInterceptor</code> is NOT in the same assembly where the <code>IAuditable</code>, <code>AuditableEntity</code> and other domain base class reside in. This would create a dependency from my base classes to NHibernate and again, I hate this :) ).<br /><br />The AuditInterceptor (snippet):<br /><img src="http://users.pandora.be/fgzone/blog/nhibintercept/interceptor1.PNG" /><br /><br />As you can see, it is very simple: I only had to implement 2 methods of the IInterceptor interface:<br /><ul><li><code>OnSave</code>, which is called when an entity is saved for the first time in the database (INSERT)</li><br /><li><code>OnFlushDirty</code>, which is called when an existing entity is dirty and has to be updated</li></ul>What I do, is check whether the entity that is to be saved implements the <code>IAuditable</code> interface, and if so, I just set the necessary properties (<code>Created</code> and <code>Updated</code>) to the appropriate values (the current DateTime).</p><p>Easy enough, simple, understandable and clean... If only this would work...<br />During testing, I got the following exception:<pre class='code-content'> ----> System.Data.SqlTypes.SqlTypeException : SqlDateTime overflow. <br />Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.<br /> at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, <br />Boolean[] notNull, SqlCommandInfo sql, Object obj, ISessionImplementor session)</pre><p>As it turns out, NHibernate doesn't 'see' the changes you make to the entity parameter that is passed to the Interceptor methods:<br /><br /><img src="http://users.pandora.be/fgzone/blog/nhibintercept/parameterbinding.PNG" /><br /><br />You can however, change the values that are in the <code>state</code> array parameter. Then NHibernate will correctly persist the changes.<br /><br />But, I do not like to 'hard-code' property names as strings for obvious reasons (if you change a property, the compiler will not detect that you should change your 'hardcoded property name string', etc...).<br /><br />Anyway, in order to get my interceptor to work, I have no other choice then messing around with the <code>propertyNames[]</code> and <code>state[]</code> parameters.<br />In order to get rid of the 'weak-typing', I added a little bit more code.<br />So, now my classes look like this:</p><ul><li><h3><code>IAuditable</code> interface</h3><br /><img src="http://users.pandora.be/fgzone/blog/nhibintercept/iauditable2.PNG" /></li><br /><li><h3><code>AuditableEntity</code> class</h3><br /><img src="http://users.pandora.be/fgzone/blog/nhibintercept/auditableentity2.PNG" /></li><br /><li><h3><code>AuditInterceptor</code></h3><br /><img src="http://users.pandora.be/fgzone/blog/nhibintercept/interceptor2.PNG" /></li></ul><p>This solution is, IMHO, elegant enough to live with, and it works. <br /><br />However, maybe someone else has a better, more elegant solution for this ? If so, I'd like to hear from you ...</p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com7tag:blogger.com,1999:blog-20196010.post-27603682301973854532008-07-01T22:21:00.005+02:002008-07-01T23:53:44.715+02:00NHibernate Session Management<p>I know that there has been written a lot about this topic, but somehow, I haven't found the 'sweet spot' concerning NHibernate Session Management in WinForms applications yet.</p><p>Some time ago, I've created a simple abstraction around the NHibernate ISession which would make it easier to use the ISession in my Winforms application.</p><P>Why do I want to clutter my presentation layer with NHibernate stuff, you ask ? Because Context is King. <br />The <a href="http://www.martinfowler.com/eaaCatalog/repository.html">Repository</a> has no notion of transactions, since the Repository doesn't know the context in where it's used.<br />Therefore, I like to start my Transaction in my WinForm app for instance, and pass the 'Transaction' to my repository, like this:</p><br /><img src="http://users.pandora.be/fgzone/blog/nhibsession/uow1.PNG" /><br />In the code above, the <code>UnitOfWork</code> class is just a simple wrapper around the NHibernate ISession which allows me to start and commit or rollback a transaction, disconnect the ISession from the Database, etc... with a minimum amount of code.</p><p>The UnitOfWork class looks like this:<br /><br /><img src="http://users.pandora.be/fgzone/blog/nhibsession/uow2.png" /></p><p>This approach also allows me to have multiple NHibernate ISessions opened in one application instance. <br />This approach also gives me full control about when to start a new UnitOfWork, and when to close a UnitOfWork.</p><p>I've been convinced that this was the way to go. Especially because I thought that you had to commit the changes you've made to an object using the same ISession as the ISession which you've used to retrieve the object if you want to avoid unnecessary <code>SELECT</code> statements. </p><p>But, thanks to my collegue Thierry (who's starting to use NHibernate as well, and acted as some kind of catalysator to me so that I picked up my NHibernate quest again), it seems that my assumptions where not true:<br />I thought that, when you save an object to the datastore, using another ISession then the ISession you've used to retrieve the object, NHibernate would first perform a <code>SELECT</code> query in order to find out whether an <code>INSERT</code> or an <code>UPDATE</code> statement should be executed.<br />This seems to be false if you do not use the 'assigned' generator class for your Id property.</p><p>So, now I'm in doubt:<ul><br /><li>do I really need to be able to have concurrent ISessions in the same application instance ? Until now, I haven't needed it yet (so, yes, that makes it a <a href="http://en.wikipedia.org/wiki/You_Ain't_Gonna_Need_It">YAGNI</a> in fact).</li><br /><li>I haven't seen anyone on the net using a similar approach. I see that everyone uses some kind of 'SessionManager' like the one Billy McCafferty has written <a href="http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx">here</a>, so this makes me doubt as well ...</li></ul></p><p>This last point is also the reason for this blogpost: I'm in doubt :)<br />Using some kind of 'SessionManager' class allows me to do the transaction demarcation where ever I want as well. Next to that, I also do not have to pass my UnitOfWork to the repository, since the repository has access to the current Session via the SessionManager as well ...<br /><br />I know that, maybe, I should just give it a try. However, I'd like to hear experiences and thoughts of other people who are using (N)Hibernate in a Rich Client environment as well.<br />How are you dealing with those (session management) issues ? What difficulties did you encounter ?</p><br /><br />Note: another post of me regarding this subject can be found <a href="http://fgheysels.blogspot.com/2007/04/nhibernate-session-management-in-domain.html">here</a><br /><br />assumptions are the mother of all fuckups.Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com3tag:blogger.com,1999:blog-20196010.post-48238769546470605362008-06-30T21:01:00.002+02:002008-06-30T21:03:09.901+02:00New Layout<p>I've changed the layout of my weblog, I hope you like it.</p><p>If you have any remarks regarding the layout, if you don't find it readable, if you miss something, please let me know.</p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com0tag:blogger.com,1999:blog-20196010.post-9097529633582796442008-06-13T18:38:00.008+02:002008-06-21T13:15:45.807+02:00Setting Up Continuous IntegrationPart II: configuring CruiseControl.NET<p>Now that we've created our <a href="http://fgheysels.blogspot.com/2008/06/setting-up-continuous-integration.html">buildscript in part I</a>, it's time to set up the configuration file for <a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET">CruiseControl.NET</a></p><br /><h2>The ccnet.config file and multiple project-configurations</h2><p>The tasks that CruiseControl.NET should execute for your project, are configured in the <a href="http://ccnet.sourceforge.net/CCNET/Configuring%20the%20Server.html">ccnet.config</a> file.<br />The ccnet.config file can contain multiple <a href="http://ccnet.sourceforge.net/CCNET/Project%20Configuration%20Block.html">project configuration blocks</a>. However, I like to have each project-configuration in it's own, separate file. In my opinion, this is much more manageable.</p><p>In order to put each project-configuration in its own XML file and import it in the ccnet.config file, you can make use of <a href="http://www.w3schools.com/dtd/dtd_entities.asp">DTD entities</a> to substitute constants with the contents of other XML files.<br />This is how I've done it:</p><pre class="code-content"><!DOCTYPE cruisecontrol [<br /> <!ENTITY project1 SYSTEM "file:D:\folder\project1_ccnet.xml.config"><br /> <!ENTITY project2 SYSTEM "file:D:\folder\project2_ccnet.xml.config"><br />]><br /><br /><cruisecontrol><br /><br /> &project1;<br /> &project2;<br /><br /></cruisecontrol></pre><p>The above piece of code makes sure that the &project1 and &project2 'placeholders' are replaced with the content of the project1_ccnet.xml.config and project2_ccnet.xml.config files.</p><p>I just saw that CruiseControl.NET 1.4 has a <a href="http://confluence.public.thoughtworks.org/display/CCNET/Configuration+Preprocessor">new approach</a> to accomplish this, however, I haven't tried it yet.</p><h2>The CC.NET config file</h2><p>The CC.NET config file is in fact very simple. You just have to put the Tasks that you've defined in your MSBuild file in the CC.NET config file.<br />Your CC.NET config file could look like this:<img src="http://users.pandora.be/fgzone/blog/msbuild/ccnetconfig.PNG" /><p>The above configuration file is by all means not complete; I've kept it simple, and left out some tasks. However, you should have an idea :)</p><h2>MSBuild doesn't support my sln file format</h2><p>The reason why I specify which executable must be used by msbuild, is very simple:<br />My project is written in VS.NET 2008, but targets the .NET 2.0 framework. So, by default, CC.NET will use the MSBuild program that has been delivered with the .NET 2.0 framework.<br />This results in an error: MSBuild doesn't recognize the VS.NET 2008 solution file format, and will stop with this error:</p><code>Solution file error MSB5014: File format version is not recognized. MSBuild can only read solution files between versions 7.0 and 9.0, inclusive.</code><p>This is offcourse due to the fact that the MSBuild that is used by VS.NET 2005 doesn't know anything about the solution file format that is used by VS.NET 2008.<br />You can solve this issue by specifying that CC.NET should use the MSBuild executable that can be found in the directory of the .NET 3.5 framework.</p><h2>The MSBuild XmlLogger Issue</h2><p>It is possible that CruiseControl.NET will not be able to execute your project, because CC.NET can't find an appropriate XmlLogger.<br />In this case, you'll find the following error in the CC.NET logfile:<br /><code>Cannot create an instance of the logger. Could not load file or assembly 'ThoughtWorks.CruiseControl.MsBuild.dll' or one of its dependencies. The system cannot find the file specified.</code><br /><p>You can solve this problem by placing the XmlLogger for MSBuild (you can find the dll <a href="http://ccnetlive.thoughtworks.com/MSBuildXmlLogger-Builds/">here</a> in your project working directory.</p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com0tag:blogger.com,1999:blog-20196010.post-30671096026557197592008-06-07T17:37:00.016+02:002008-06-07T18:45:26.683+02:00Setting Up a Continuous Integration process using CruiseControl.NET and MSBuild.Part I: creating the MSBuild build script<h2>Intro</h2><p>I’ve been struggling lately to get a new project that I’ve started at work, under <a href="http://en.wikipedia.org/wiki/Continuous_Integration">Continuous Integration</a>.<br />Although I’ve used <a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET">CruiseControl.NET</a> & <a href="http://nant.sourceforge.net/">NAnt</a> in my previous project for CI purposes, things didn’t go so smooth now ... <br /><br />In my current project, I’m using Visual Studio.NET 2008 and targetting .NET 2.0. <br /><br />Now, I wanted to use <a href="http://msdn.microsoft.com/en-us/library/wea2sca5.aspx">MSBuild</a> for the build process and that’s where it all started.</p><p>I had to spent some time searching on the Net in order to get everything working like I wanted. It seems that there’s no single source of documentation for <a href="http://msdn.microsoft.com/en-us/library/wea2sca5.aspx">MSBuild</a> & <a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET">CC.NET</a> which addresses all the problems that I’ve encountered. <br />So, the intention of this article, is to help other people setting up a CC.NET environment with MSBuild, and it will also serve as a reference for me, so that I can grab back to it when needed. :)</p><h2>Requirements</h2><p>What I wanted to achieve, is very simple:<br /><br />I have a build machine where CruiseControl.Net is installed. This machine is already used for another project of mine for which I’m using NAnt for the build process.<br /><br />The new project that I’ve started, is being developped in VS.NET 2008, targets the .NET 2.0 framework and is under SourceControl via Visual SourceSafe.<br /><br />I wanted to have a CI process that regularly looks in VSS and, when something has changed, performs the following tasks:<br /><ul><br /><li>Make sure that the latest buildscript will be used</li><br /><li>Clean the source directory</li><br /><li>Get the latest version of the codebase out of Visual SourceSafe</li><br /><li>Build the entire codebase</li><br /><li>Execute the unit tests that I have using <a href="http://www.nunit.org/index.php">NUnit</a></li><br /><li>Perform a <a href="http://en.wikipedia.org/wiki/Static_code_analysis">statical code analysis</a> using <a href="http://www.nunit.org/index.php">FxCop</a></li><br /></ul></p><br /><!--adsense--><h2>The MSBuild build-script</h2><p>In order to automate all the steps above, I needed to have a build-script first which I can execute using MSBuild.<br /><br />Such a script is also handy when the application you’re building consists of numerous VS.NET solutions; instead of opening each solution separately in Visual Studio, compiling it, opening the next solution ..., you can build the entire codebase using a single command line. <br />This is quite handy and productive, I can tell you :)</p><p>For every ‘task’ (clean source directory, get latest, build codebase, etc… ) that I want to execute, I’ve created a <a href="http://www.nunit.org/index.php">Target</a> in the build script.</p><p>A first little problem I encountered was that MSBuild doesn’t contain any tasks that would allow you to get a latest version out of VSS, run <a href="http://www.nunit.org/index.php">NUnit</a> <a href="http://en.wikipedia.org/wiki/Unit_test">unit-tests</a> or perform a code analysis with FxCop out of the box.<br />Fortunately, there exists an open source project called the <a href="http://msbuildtasks.tigris.org/">'MSBuild Community Tasks Project'</a> which contains additional tasks that can be executed by MSBuild. This means that you don’t need to <a href="http://community.bartdesmet.net/blogs/bart/archive/2008/02/15/the-custom-msbuild-task-cookbook.aspx">write your own MSBuild Tasks</a>.</p><h3>Skeleton of the buildscript</h3><p>Before creating the Targets, I’ve defined a few properties which I will use in all the tasks:<br /><img src="http://users.pandora.be/fgzone/blog/msbuild/msbuild_skeleton.PNG" /><br /><br />I define the working directory (where my source can be found) as the builddir, and a directory where the assemblies that have been build should be placed (outputdir).<br />Next to that, I also have an artifactsdirectory where the results of the unittests and code analysis will be put.<br /><br />The last line in the above code is necessary so that we can use the additional MSBuild Tasks that can be found in the MSBuild Community Tasks Project.</p><p>Now, we can start creating our 'Targets'.</p><h3>Clean Target</h3><p>I want to have the possibility to start from a 'clean sheet', so I really need a Target which justs deletes everything that can be found in my builddir and outputdir.<br />This Target is very simple; you just have to make use of the <a href="http://msdn.microsoft.com/en-us/library/7wd15byf.aspx">Delete Task</a>:<br /><br /><img src="http://users.pandora.be/fgzone/blog/msbuild/msbuild_cleantarget.PNG" /></p><h3>Getlatest Target</h3>In order to get the latest version of the source out of SourceSafe, I’ve created the following step:<br /><br /><img src="http://users.pandora.be/fgzone/blog/msbuild/msbuild_getlatesttarget.PNG" /><br /><br />Here, I just make use of the VssGet Task that is part of the <a href="http://msbuildtasks.tigris.org/">MSBuild Community Tasks project</a>.<br />Also, notice that this Target depends on the createdirs Target; this means that, when you execute the getlatest Target, the createdirs Target will be executed before the getlatest Target is executed.</p><p>The createdirs tasks looks like this:<br /><br /><img src="http://users.pandora.be/fgzone/blog/msbuild/msbuild_createdirstask.PNG" /></p><h3>BuildAll Target</h3><p>This is the first target where I’ve had some issues, although it’s task is very trivial:<br />Compile and build everything that can be found in the <code>$(builddir)</code>, and make sure that the assemblies that have been built are placed in the <code>$(outputdir)</code>.<br /><br />It seemed very easy to do, since I found out that MSBuild.exe (which is the program I use to compile the code) had a property <code>OutputDir</code>. So, it would be fairly easy to set this property to the <code>$(outputdir)</code> variable.<br /> <br />Alas, to no avail. My assemblies were never copied to the output-directory. Eventually, I discovered that there also exists an <code>OutputPath</code> property, so I tried it. This seemed to work.<br />So, the buildall Target looks like this:<br /><br /><img src="http://users.pandora.be/fgzone/blog/msbuild/msbuild_buildalltarget.PNG" /></p><p>Offcourse, you can put multiple solution files in the Projects attribute of the <a href="http://msdn.microsoft.com/en-us/library/0k6kkbsd.aspx">MSBuild</a> Task. <br />You’ll have to separate the <a href="http://msdn.microsoft.com/en-us/library/bb165951(VS.80).aspx">sln files</a> with a semicolon.</p><h3>NUnit Target</h3><p>This Target is quite simple:</p><img src="http://users.pandora.be/fgzone/blog/msbuild/msbuild_nunittask.PNG" /><p>With this Target, I run the NUnit tests that have been written in my test assembly. (I tend to name all my Test-assemblies <code><projectname>.Tests.dll</code>).<br /><br />The results of the unit-tests procedure are placed in the artifacts directory as an XML file. In this way, I can easily incorporate the test-results in my CC.NET report (more on this later).</p><h3>FxCop Target</h3><p>This one was a bit cumbersome.<br />I started out writing this Target with the FxCop task that can be found in the MSBuild Community Project; it looked like this:</p><br /><img src="http://users.pandora.be/fgzone/blog/msbuild/msbuild_fxcop1.PNG" /><p>The reason why I do not apply the output XSL stylesheet, is very simple: I want CC.NET to display the results on the Dashboard, so CC.NET should read the XML file, and apply the XSL stylesheet.</p><p>Now, this Target just worked fine on my development box. However, on my ‘build server’ *ahum* (my previous dev Workstation), I couldn’t get it working.<br />On the build machine, I constantly kept getting errors. <br />Apparently, msbuild was trying to locate FxCop in <code>C:\Program Files\Microsoft FxCop 1.32</code>, but I don’t have this old version of FxCop installed. <br />I’m using FxCop 1.36 beta instead.</p><p>Therefore, I eventually opted to put the path where FxCop is installed in my %PATH% environment variable, and decided to use the <a href="http://msdn.microsoft.com/en-us/library/x8zx72cd.aspx"><code>Exec</code></a> Task so that I could call the <a href="http://msdn.microsoft.com/en-us/library/x8zx72cd.aspx">fxcopcmd</a> tool:</p><img src="http://users.pandora.be/fgzone/blog/msbuild/msbuild_fxcop2.PNG" /><p>In order to keep my build script a bit readable, I’ve created an <a href="http://msdn.microsoft.com/en-us/library/646dk05y.aspx"><code>ItemGroup</code></a> in where I define all the command-line arguments that I want to pass to <code>FxCopCmd.exe</code>.</p><p>By default, the items that are defined in an <a href="http://msdn.microsoft.com/en-us/library/646dk05y.aspx"><code>ItemGroup</code></a> will be concatenated with a semicolon. This is something I do not wanted offcourse, since command line arguments should be separated by a space.<br />It is easy to define that the items should be separated by a space:</p><pre class="code-content">@(Args, ' ')</pre><p>There’s a litle sublety with the Exec command however: it doesn’t work well when you have a commandline argument that is a path which contains a space. You should escape such paths with quotes, but I haven’t succeeded in getting it to work with MSBuild yet ... </p><br /><h2>Executing Targets via MSBuild</h2><p>Now that we’ve defined all the Targets, we need to see if they work offcourse.<br />Executing a Target is fairly easy:</p><p>Just open up a VS.NET command prompt (or open a regular command prompt and make sure that the path to the MSBuild.exe utility is in your path environment variable), and navigate to the location where your msbuild build-script is located.</p><p>Then, you just execute MSBuild, make sure that your build script is used, and tell MSBuild which target he should execute. You can also override the default values of the parameters (like $(outputdir) ) that we’ve defined in our script.<br /><br />For instance:<br /><br /><code>msbuild myproject.msbuild /t:buildall /p:outputdir=r:\myproject\release /p:buildmode=release</code></p><p>I think that this is enough text for today. I will soon post a subsequent article in where I’ll explain how to use this script in CruiseControl.NET.</p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com1tag:blogger.com,1999:blog-20196010.post-85660757396549251752008-04-20T20:09:00.002+02:002008-04-20T20:22:27.853+02:00using directives within namespaces<p>Sometimes, I come across code examples where the programmer puts his using directives within the namespace declaration, like this:</p><pre class='code-content'>namespace MyNamespace<br />{<br /> using System;<br /> using System.Data;<br /><br /> using SomeOtherNamespace;<br /><br /> public class MyClass<br /> {<br /> }<br />}</pre></p><p>I am used to put my using directives outside the namespace block (which is no surprise, since VS.NET places them by default outside the namespace declaration when you create a new class):</p><pre class='code-content'>using System;<br />using System.Data;<br /><br />namespace MyNamespace<br />{<br /> public class MyClass<br /> { <br /> }<br />}</pre><p>So, I'm wondering: what are the advantages of placing the using directives within the namespace declaration ?<br />I've googled a little bit, but I haven't found any clue why I should do it as well. Maybe you'll know a good reason, and can convice me to <a href="http://fgheysels.blogspot.com/2006/09/changing-default-access-modifier-when.html">adapt my VS.NET templates</a> ?<br /></p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com0tag:blogger.com,1999:blog-20196010.post-49301552518049690872008-03-12T17:31:00.004+01:002008-03-12T17:48:59.646+01:00VS.NET 2008: Form designer not working on Windows Vista<p>I installed Visual Studio.NET 2008 on my Vista workstation at work. I was keen to work with it, but apparently, my workstation had some issues.</p><p>When I started VS.NET 2008, and created a new WinForms project, I received the following error when I wanted to open a Form in the designer:</p><quote>The Service Microsoft.VisualStudio.Shell.Interop.ISelectionContainer already exists in the service container</quote><br /><br /><img src="http://users.pandora.be/fgzone/blog/vsnet2008errorvista.png" alt="ISelectionContainer" /><br /><br /><p>I've searched a bit on the Internet, and it seems that I was not the only person who was having this problem.<br />However, nobody seemed to have a solution for this problem, and according to <a href="https://connectbeta.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=311949">Microsoft, this problem was not reproducable</a> ...<br /><br />Eventually, I found a website where someone said you had to install SP1 for .NET 2.0 and SP1 for .NET 3.0.<br />Unfortunately, these service packs are not supported by Vista.<br /><br />I was however able to install the updates KB110806 and <a href="http://support.microsoft.com/kb/929300">KB929300</a> and installing these 2 updates, fixed my problem</p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com0tag:blogger.com,1999:blog-20196010.post-39703873483072137262008-01-28T11:31:00.000+01:002008-01-28T11:41:09.499+01:00Debugging the .NET framework<p>As I've written <a href="http://fgheysels.blogspot.com/2007/10/new-debugging-experience-in-vsnet-2008.html">earlier</a>, Visual Studio.NET 2008 makes it possible to debug code that can be found on a source server.<br />I think this can be very interesting and I can think of numerous situations where this can be very handy.<br />Suppose you work in a company that uses an in-house developped framework, and you're building an application that uses this framework.<br />If you experience some strange behaviour inside your application, you can debug your code and step into the code of the framework to see if the company's framework has a bug.</p><p>I've read that Microsoft has setup a source server which contains the debug-symbols of the .NET framework, so, as from this month, it is possible to step into the .NET framework source-code as well!<br />Setting up VS.NET 2008 to enable this is very simple; you can find a step-by-step guide <a href="http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx">here</a>.</p><br /><p>The Mozilla team also have a symbol server. You can read more about it <a href="http://developer.mozilla.org/en/docs/Using_the_Mozilla_symbol_server">here</a></p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com0tag:blogger.com,1999:blog-20196010.post-28487365776430880872008-01-15T12:33:00.001+01:002008-02-26T20:50:51.718+01:00Cannot open log for source {0} on Windows 2003 Server<p>I am writing an application which uses some .NET remote components that are hosted in IIS on a Windows 2003 Server.<br />When the remote component throws an exception, the exception information should be written to the EventLog on the Windows 2003 Server; however, Win2k3 seems to be a bit restrictive when a component that is hosted in IIS wants to write to the eventlog.<br />Although the component does not run under the IIS_WPG or ASPNET account (I am using Windows Impersonation), I always received the following exception when the .NET remote component wanted to write something to the eventlog:</p><div style='code'>Cannot open log for source {0}. You may not have write access. Access is denied</div><p>You can get rid of this behaviour and make sure that the error is indeed written to the EventLog by following the steps below:</p><ul><li>Open the registry on the Win2k3 server using regedit</li><li>Locate the <code>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog\Application key</li><li>Find the CustomSD key and append the following string to the existing value: <code>(A;;0x0002;;;AU)</code></li></ul><p>Now, the (impersonated) remote component should have rights to write to the EventLog.</p><p>Now, what is the meaning of the string you've just added to the CustomSD key ?</p><ul><li>A stands for <code>SDDL_ACCESS_ALLOWED</code>. (See <a href="http://msdn2.microsoft.com/en-us/library/aa374928.aspx">ACE strings</a>).</li><li>0x0002 stands for <code>ELF_LOGFILE_WRITE</code>. (See also <a href="http://msdn2.microsoft.com/en-us/library/aa363658.aspx">Event Logging Security</a></li><li>AU stands for Authenticated Users. (See also <a href="http://msdn2.microsoft.com/en-us/library/aa379602.aspx">SID strings</a></li></ul>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com4tag:blogger.com,1999:blog-20196010.post-35717320970366738392007-11-03T16:10:00.000+01:002007-11-03T16:25:33.354+01:00Castle Windsor and ActiveRecord<p>I sometimes read blogposts where people mention <a href="http://www.castleproject.org/container/index.html">Castle Windsor</a> and <a href="http://www.castleproject.org/activerecord/index.html">Castle's ActiveRecord</a>, so I decided to have a little peek at these two projects.</p><p>Castle Windsor is an <a href="http://martinfowler.com/articles/injection.html">IoC container</a> and ActiveRecord is an implementation of the <a href="http://martinfowler.com/eaaCatalog/activeRecord.html">Active</a> <a href="http://davidhayden.com/blog/dave/archive/2006/06/10/2984.aspx">Record</a> pattern which internally uses NHibernate.<br />These projects look very interesting, and I'd like to make use of them in a little hobby-project before using it in a real-world project</p><p>Is there anybody who has used one (or both) of these projects in a real world scenario and who wants to share his (or her) findings ? </p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com2tag:blogger.com,1999:blog-20196010.post-13373150180927360362007-10-24T22:07:00.000+02:002007-10-24T22:27:09.405+02:00New debugging experience in VS.NET 2008<p>As I was reading a bit on <a href="http://community.bartdesmet.net/blogs/bart/default.aspx">Bart De Smet's weblog</a> today, I came accros an interesting post where Bart <a href="http://community.bartdesmet.net/blogs/bart/archive/2007/10/03/arrived-in-redmond-some-hot-net-news.aspx">talks about a new 'debugging experience in VS.NET 2008</a>.</p><p>It seems that Microsoft will release the source code for the .NET Framework libraries, and that there will be an <a href="http://weblogs.asp.net/scottgu/archive/2007/10/03/releasing-the-source-code-for-the-net-framework-libraries.aspx">integrated debugging support in VS.NET 2008</a>. <br />This means: when debugging your code, it should be possible to 'step into' the code of the .NET framework classes. <br />I think this is great!</p><p>I've also read another interesting thing on Bart's weblog: Bart will be working in the MS HQ's in Redmond, where he'll work on WPF. That must be a great job, and I'd like to wish Bart a lot of succes!</p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com0tag:blogger.com,1999:blog-20196010.post-78089104771706727802007-10-18T20:20:00.000+02:002007-10-18T20:31:41.200+02:00MSDN RampUp<p>Microsoft has set up a programme in which you can take part to gain new or refresh your existing .NET development skills.<br />This programme is called 'MSDN Ramp Up'. It is an online course with a lot of course material and online virtual labs.</p><p>The nice thing about this Ramp Up programme, is that Microsoft has made different 'tracks', which are tailored to the existing experience and knowledge of the student.<br />There are four tracks available:</p><ul><li>Aspiring Developer; which is suited for people who have no prior programming experience, but want to learn programming with MS technology</li><br /><li>Java Developer; this track is for Java developers who want to gain knowledge about the .NET framework and want to learn programming in C#</li><br /><li>MS Visual Basic 6.0 developer; lets existing VB 6 developers become proficient in .NET and VB.NET 2005</li><br /><li>MS VS.NET 2002/2003 developer; introduces the .NET 1.x developer with the improvements and changes in the .NET 2.0 framework</li></ul><br />If you want to learn more about this programme, or want to take part in it, then visit <a href="http://msdn2.microsoft.com/en-us/rampup/default.aspx">this website</a>.Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com0tag:blogger.com,1999:blog-20196010.post-5773458252272627832007-09-28T18:51:00.000+02:002007-09-28T18:55:24.423+02:00MS LEAP Programme, yet another rant.A while ago, I received an e-mail with an invitation to take part in the <a href="http://www.microsoft.com/belux/msdn/nl/leap/default.mspx">MS LEAP programme</a>.<br /><br />This looked very interesting, so I asked my employer if I could take that course and if my employer could help me bear the costs.<br />A few days later, I received the answer that I could and that they (the company where I work) would bear the majority of the cost. \o/<br /><br />Now, today, I wanted to subscribe but unfortunately, the program is already fully booked. :(<br /><br /><sub>The <a href="http://fgheysels.blogspot.com/2007/09/auto-formatting-in-vsnet-2005-does-not.html">ranting</a> doesn't stop. :( </sub>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com3tag:blogger.com,1999:blog-20196010.post-13726249981176395782007-09-27T22:09:00.000+02:002007-09-27T22:17:09.096+02:00Auto-Formatting in VS.NET 2005 does not work anymore<p>After a harddisk-crash, I had to reinstall Visual Studio.NET 2005.<br />As I started programming again after it was re-installed, I noticed that the 'auto-formatting' function of VS.NET didn't work anymore ...</p><p>This is very strange, and very annoying once you're used to it. I've verified my options, and they're set the way I want too. <br />The options:<br /><ul><li>Automatically format completed statement on;</li><li>Automatically format completed block on }</li></ul><br />are enabled. However, when I type a ; or a }, the code is not being formatted at all...<br />When I use the shortcut 'Ctrl + E, D (format document)', my current document is formatted.</p><p>I've no idea why this doesn't work anymore. I've just made a fresh install of VS.NET. <br />Is there anybody who has experienced this 'annoyance' as well, and if so, how did you fix it ?<br />In other words: if there's anybody out there who knows how to fix it, please let me know. :)</p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com2tag:blogger.com,1999:blog-20196010.post-13896624964112223752007-08-13T20:30:00.001+02:002007-08-13T20:49:31.984+02:00Cleaning a Keyboard<p>My keyboard is about 5 years old, and it has been used extensively. During these years, it has become more and more filthy.<br />Now, I thought the time has come to do something about it. Basically, I had two options:</p><ul><li>Buy a new keyboard</li><li>Clean my keyboard</li></ul><p>I thought the second option was more of a challenge then just buying a new one.<br />So, this is what I did.</p><p>To give you an idea of how filthy my keyboard actually was, I've made a picture of it:</p><p style="text-align: center;"><img src="http://users.pandora.be/fgzone/blog/IMG_3915.jpg" alt="filthy keyboard" /></p><p>After I took a picture of the layout of my keyboard, I removed all keys from the board. You can imagine that the picture I've taken comes in quite handy when I wanted to place the keys back.</p><p style="text-align: center;"><img src="http://users.pandora.be/fgzone/blog/IMG_3918.jpg" alt="removing keys from keyboard" /></p><p>I've put all the keys in a bucket of water, and cleaned them.<br />After removing all the keys, the keyboard looked like this:</p><p style="text-align: center;"><img src="http://users.pandora.be/fgzone/blog/IMG_3923.jpg" alt="stripped keyboard" /></p><p>Hmm, this contains a lot of filth as well. I made good use of the vacuum-cleaner to remove most of it.<br />Then, when all the cleaned keys were dry again, I could put all the keys back to where they belong. The result: a clean keyboard:</p><p style="text-align: center;"><img src="http://users.pandora.be/fgzone/blog/IMG_3932.jpg" alt="clean keyboard" /></p><p>It was quite some work, but, devving with a clean keyboard is much nicer then using a dirty one. ;)</p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com5tag:blogger.com,1999:blog-20196010.post-73929653906541990312007-08-08T19:37:00.000+02:002007-08-08T19:43:41.332+02:00C# 3.0: new language features<p>I've already written <a href="http://fgheysels.blogspot.com/2006/01/c-30-orcas-playing-with-linq.html">a blogpost</a> regarding LINQ and new language features that we may expect in C# 3.0 a while ago.<br /><a href="http://blogs.zdnet.com/microsoft/?p=564">Since the release of VS.NET 2008 and thereby C# 3.0 is coming closer and closer</a>, I was planning to write an updated blogpost about the new language features in C# 3.0.</p><p>However, I've noticed that John Papa has already written an excellent article already concerning the language enhancements in .NET 3.5, so I've decided to just link to that article:</p><p><a href="http://www.simple-talk.com/dotnet/.net-framework/.net-3.5-language-enhancements/">.NET 3.5 Language Enhancements</a><br />That's much easier for me, and it saves me some time. :)</p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com0tag:blogger.com,1999:blog-20196010.post-91891096066148752172007-08-04T10:59:00.000+02:002007-08-04T11:11:04.843+02:00XSD Schema for configuration of Log4Net<p>A few days ago, I was playing around with <a href="http://logging.apache.org/log4net/">log4net</a>, the open source framework that allows you to easily log messages in an application.</p><p>Since log4net is very configurable, I wanted to have Intellisense in Visual Studio.NET when I'm editing the log4net configuration. <br />Therefore, I need a schema definition for the log4net XML configuration file so that I can set up the Intellisense for the log4net configuration as I did <a href="http://fgheysels.blogspot.com/2006/04/net-20-could-not-find-schema.html">here</a> for NHibernate.</p><p>Unfortunately, it seems that the source of log4net doesn't contain such an XSD.<br />So, before I take the time and effort to create such an XSD, I wonder if anyone has already made such an XSD for log4net and is willing to share it. :) </p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com2tag:blogger.com,1999:blog-20196010.post-39192566555879443492007-07-27T20:39:00.001+02:002007-07-27T21:09:19.334+02:00NHibernate & MS Access: problems with autonumber fields<p>I was playing around with NHibernate and MS Access a bit the other day, and I ran into an annoying problem.<br /><br />When I tried to save an object which maps to a table wich has an 'autonumber' field, I received this error:<br /><br /><em>a different object with the same identifier value was already associated with the session: 0</em><br /><br />It looked like NHibernate was unable to retrieve the ID that has been given to the new record in the database. <br /><br />So, I decided to set up <a href="http://logging.apache.org/log4net/">log4net</a> to see if I could find any clue in the logs about the reason for this problem.</p><p>As it turned out, it seems that NHibernate was closing the database-connection between the <code>INSERT</code> and the <code>SELECT @@identity</code> statements.</p><pre class="code-content">DEBUG NHibernate.SQL - INSERT INTO table ...<br />DEBUG NHibernate.Connection.DriverConnectionProvider - Obtaining <br />IDbConnection from Driver<br />DEBUG NHibernate.Impl.BatcherImpl - Closed IDbCommand, open IDbCommands: 0<br />DEBUG NHibernate.Impl.ConnectionManager - aggressively releasing <br />database connection<br />DEBUG NHibernate.Connection.ConnectionProvider - Closing connection<br />DEBUG NHibernate.Impl.BatcherImpl - Opened new IDbCommand, open IDbCommands: 1<br />DEBUG NHibernate.Impl.BatcherImpl - Building an IDbCommand object for <br />the SqlString: select @@identity<br />DEBUG NHibernate.SQL - select @@identity</pre><p>After some research in the Hibernate documentation and on the Internet, I discovered that this is caused by the 'connection release mode'.<br /><br />The default connection release mode seems to release the connection after each SQL statement, so obviously, Access is not able to determine the correct ID of the last inserted record, since the <code>select @@identity</code> command must be executed on the same connection as its related <code>INSERT</code> statement.</p><p>Now that we know what caused this problem, it is easy to fix it: just make sure that you do not use the default connection release mode when using NHibernate with MS Access. <br /><br />To do so, you should specify the connection release mode in your NHibernate configuration file like this:</p><pre class="code-content"><hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"><br /> <session-factory><br /> <property name="hibernate.connection.release_mode">on_close</property><br /> </session-factory><br /></hibernate-configuration></pre><p>More information regarding the different options / settings for the connection-release mode can be found <a href="http://www.hibernate.org/hib_docs/reference/en/html/transactions.html">here</a>.Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com1tag:blogger.com,1999:blog-20196010.post-51340781566052311342007-07-18T19:08:00.000+02:002007-07-18T19:23:16.644+02:00Counting in SQL Server: SELECT COUNT(*) != SELECT COUNT(columnname)<p>Today, I've learned something new; or rather, I was being pointed out something that I didn't know about:<br />It seems that, doing a <code>SELECT COUNT(columnname)</code> does not always give you the same results as doing a <code>SELECT COUNT(*)</code>. As it was pointed out to me, doing a <code>SELECT COUNT(columnname)</code> returns the number of rows in the resultset in where the value of the field in 'columnname' is NOT NULL.</p><p>This means that, given the following set of data:</p><table><tr><td><b>id</b></td><td><b>name</b></td></tr><tr><td>1</td><td>Name1</td></tr><tr><td>2</td><td>NULL</td></tr><tr><td>3</td><td>Anothername</td></tr></table><br /><p>performing this statement:<pre class="code-content">SELECT COUNT(*) FROM table</pre>gives us 3 as a result, while doing this:<pre class="code-content">SELECT COUNT(name) FROM table</pre> returns 2 as result.</p><p>I really was ignorant to this behaviour, as I do (or did), most of the time a <code>SELECT COUNT(1) FROM table</code> instead, since I thought that this was the most performant option, but this also seems to be not true in some circumstances; <br />doing a SELECT COUNT(*) enables SQL Server to use indexes in calculating the number of results in a resultset.</p><p>For a more thourough article about this, I'd like to refer to <a href="http://www.sqlservercentral.com/columnists/chedgate/adviceoncount_printversion.asp" target="_blank">this article on SQL Server Central</a>.<p><small>Thanks to Peter De Boer for pointing this out</small></p>Frederik Gheyselshttp://www.blogger.com/profile/15416462808733991725noreply@blogger.com3