Skip to main content

Posts

Showing posts from October, 2009

Auditing user actions

I want to be able audit user actions on the domain model - I want to track when & what they've changed. Now I can do this at the course grained level using nHibernate event listeners, they can tell me when an entity is loaded, saved, updated etc. But without interrogating the state of the entity in depth I'm unable to determine what's gone on between loading an entity and it being saved. This is where the idea of domain events comes the rescue - the idea of generating events from the domain model. Now this could be done using the standard .Net event pattern, but as described in the above link the use of a decoupled domain events is way more powerful -the use of an intermediary ('DomainEvents' class) to decouple the domain model from the event handlers is simplistic and beautiful. So now I can have an auditing service listening to both nHibernate & the domain model to track user actions across the domain and when a domain entity is persisted I can then push o...

Unstructured development opportunity

Anyone spot the oxymoron in the snippet of a job spec I received today: Ability to handle multiple competing priorities, work with minimal formal specifications, and deliver at the highest levels. It then goes on to say: Experience of designing, building and maintaining sophisticated automated trading applications with a large userbase and significant business dependency. Equity, future and option experience and working closely with business users. There really must be some telepathic developers out there - no specification but expected to do some kind of BUF design.. I believe the people who run and develop in these type of teams have no experience of working in environments with any kind of formal structure and expect to spend most of their time & money on support & maintenance - but there again the opportunity is everything in the finance sector! Also they will say they're doing 'Agile', note they don't do 'agile'. Awkward Coder

Property setters are just wrong!

In general I think the use of property setters on classes is a sign of bad class design and a lack of OO principles - in most cases when you modify the 'state' of a class some 'behaviour' is invoked whether it be implicit or explicit; e.g. when I change the address on a user account I want to make sure the address object has been populated (at least). So these days I've started to design classes that have public getters & private setters, and if you want to modify state you are required to call a method, e.g. 'ChangeAddress'. This is nothing new, there are plenty of examples out there. So in the example below 'Token' is property that's defined when the object is constructed and 'Path' is a property which is modified by calling the method 'ChangePath'. public class File : ObservableEntity<int> { private string _path; private Guid _token; private readonly IExtractFileProperties _propertiesEx...

Lambda beats magic string

Okay magic strings are a pain, in the worst cases they're bugs waiting to happen but I've been living with the following for while and it's always been nagging me when ever I look at the code. public abstract class Observable<T> : IEntity<T>, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged = delegate { }; private T _id; public virtual T Id { get { return _id; } private set { ChangePropertyAndNotify(ref _id, value, "Id"); } } protected void ChangePropertyAndNotify<T2>(ref T2 value, T2 newValue, string propertyName) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } So after reading the MSDN article by Jeremy Miller and the example of using the Lambda expression in Fluent nHibernate mapping syntax I thought can we apply this to the above to remove the magic string "Id", and the answer is yes! public abstract class Observable<T> : IEntity<T>, INotifyPropertyChang...

Using repositories inside a domain entity

If you follow the principles of DDD you'll be well aware of the persistence ignorance discussion\argument. I believe domain entities should be agnostic of the persistence layer and therefore not statically bound at compile time. Overall I'm happy with this approach but it does give issues when trying to place certain business logic on the entity that requires access to some service (read repository). Now obviously you can use the 'double-dispatch' approach and pass in the repository via an interface and only couple the entity to an interface, but to me this still seems a level of coupling that's unacceptable - usually we see these interfaces in an 'interfaces' project, to couple this to the domain model (entities) seems wrong. So to get round this you can use functional programming, to be more specific you can use a lambda expression. So imagine I have a Registration entity and it has responsibility for generating the user name from other data contained in ...

Functional intro

Jeremy Miller has a great article in this months MSDN magazine introducing functional programming for the OO developer. If you've been using the features of .Net 3.5 - Func, Action, etc. you've probably been using these techniques & patterns without realising. I know I have. It's a good read! You might also be interested in Jon Skeet's new book release later this month. Awkward Coder