November 27, 2008 11:22 by Nigel Sampson
So I decided to use Blog Engine .NET for the foundation of this blog, I
suspect I'll move to something homegrown when I start putting together
a product oriented site, but for now it certainly scatches the itch.
So what did I think of it?
It's an excellent blogging solution out of the box, the only things I
did that I disagreed with were mostly matters of opinion in such things
as urls and I could have changed this since it's open source.
It's only when I wanted to create my own theme that I started to run
into problems. For a number of the pages the html generation was all
over the place, a crazy mixture of strings in the code behind,
generation of html dom (new HtmlTable() etc) and in the aspx file
itself. Overall this slowed me down in altering the look and feel, and
for some pages I gave up entirely. The ajax on the contact us and
comments pages seem very fragile as well.
In conclusion, for out of the box functionality it's great, for
altering the look and feel it'll require quite a bit of untangling and
time investment to get it right.
At some point I'll invest time into MVC and Silverlight as a learning
exercise and see what I can do myself (all programmers think they can
do everything better), but for me it's balancing "Not Invented Here"
against having a real world example to learn a new set of technologies.
November 23, 2008 23:39 by Nigel Sampson
As you can see I've moved things to a new blog, with a new name, design
and software. For me things like this are fresh starts which help to
develop new habits, the excitement of something new means new habits
start and with effort I can keep them going.
So what is Compiled Experience? (thanks to Barry
for the name), It's a new place for me blog, mostly around Silverlight
and Dynamic Data, to share what I've learned and talk about those damn
bugs that never have an answer anywhere else on the web.
I'm
especially looking forward to doing some work around Silverlight and
WPF Line of Business Applications and providing UI scaffoling
capabilities.
September 8, 2008 20:26 by Nigel Sampson
In earlier posts I talked about about creating Domain Driven Design
style repositories using Linq to SQL. These allowed us to swap between
Linq to SQL repositories and In Memory ones easily (and really anything
that could support IQueryable<T>, this ensured some very nice
testabiliy. In this post I thought I'd go over some it again as well as
a some refactoring I had done to simplfy things, as well as how to
create simple Active Record style data access on top of our
repositories and therefore still ensuring our testability.
Our IUnitOfWork and its implementations (SqlUnitOfWork
and InMemoryUnitOfWork) haven't changed. However given that
IDataSource<T> and IRepository<T> are essentially the same
I decided to remove IDataSource<T>. Now that we have two
implentations of IRepository<T> (InMemoryRepository and
SqlRepository) we need one that uses these repositories and forms the
base class for our aggregate repositories.
This
base Repository<T> forms the foundation for it all, internally
it's only really a decorator around the actual specialised repository
that's accessed from the current Unit Of Work (more about this in a
later post).
public class Repository<T> : IRepository<T> where T : class
{
public static IRepository<T> Current
{
get
{
return UnitOfWork.Current.GetRepository<T>();
}
}
public Repository()
{
}
public IQueryable<T> GetAll()
{
return Current;
}
public virtual void Update(T entity)
{
Current.Update(entity);
}
public virtual void Update(IEnumerable<T> entities)
{
Current.Update(entities);
}
public virtual void Delete(T entity)
{
Current.Delete(entity);
}
public virtual void Delete(IEnumerable<T> entities)
{
Current.Delete(entities);
}
public virtual void Save(T entity)
{
Current.Save(entity);
}
public virtual void Save(IEnumerable<T> entities)
{
Current.Save(entities);
}
public IEnumerator<T> GetEnumerator()
{
return Current.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
Type IQueryable.ElementType
{
get { return Current.ElementType; }
}
Expression IQueryable.Expression
{
get { return Current.Expression; }
}
IQueryProvider IQueryable.Provider
{
get { return Current.Provider; }
}
}
Active Record, this seems to be
the way a lot of people think data access should be, a few static
methods on your classes and away you go. From a testability point of
view I feel repositories certainly work better, but for smaller data
driven applications Active Record can certainly be the way to go.
I'd
like to support both camps with this system so lets build on top of
what we already have, first we'll need a static accessor to the current
repository, we can do that through the unit of work, but since we
already that in our base class we'll just expose that. Now anytime we
need our repository it can be accessed through
Repositor<T>.Current. This lets us built our ActiveRecordBase.
public abstract class ActiveRecordBase<T> where T : ActiveRecordBase<T>, IIdentifiable
{
public static IQueryable<T> GetAll()
{
return Repository<T>.Current;
}
public static T GetById(int id)
{
return GetAll().Where(i => i.Id == id).FirstOrDefault();
}
public static IQueryable<T> Find(Expression<Func<T, bool>> predicate)
{
return GetAll().Where(predicate);
}
public static void Save(T entity)
{
Repository<T>.Current.Save(entity);
}
public static void Update(T entity)
{
Repository<T>.Current.Update(entity);
}
public static void Delete(T entity)
{
Repository<T>.Current.Delete(entity);
}
}
One important item in there is the IIdentifiable interface, I've seen
some posts around either using Dynamic Linq or reflection to implement
the GetById method but I prefer this. This won't work for all objects
that dont't have an identity column, but for most of mine it's fine.
This allows us something really cool, a kinda mix in. A conditional extension method on the repository class.
public interface IIdentifiable
{
int Id
{
get;
}
}
public static T GetById<T>(this IRepository<T> repository, int id) where T : class, IIdentifiable
{
if(repository == null)
throw new ArgumentNullException("repository");
return repository.Where(i => i.Id == id).FirstOrDefault();
}
public partial class Product : ActiveRecordBase<Product>, IIdentifiable
{
public static IQueryable<Product> GetOnSaleProducts()
{
return GetAll().Where(p => p.IsOnSale);
}
}
Next post I'll set up a unit test base class for the in-memory tests and managing our unit of work.
August 20, 2008 20:25 by Nigel Sampson
So a hard drive was failing (sounding like an angle grinder). Not
wanting to risk extracting the data myself before it failed I sent back
to the professionals since it was under warranty.
New Zealand Post lost my hard drive... Tracking numbers are of no use if no one ever scans the barcode.
Bugger
August 18, 2008 20:19 by Nigel Sampson
I read a post a few weeks ago about feeling the pain of some software
development practises including such things as untestable code and
tight coupling. I'd really like to post a link to it however Google
Reader search isn't at all helping in helping me re find it. But first
some history.
I feel like I'm in that
position now, during my previous employment I encountered during my
R&D a lot of what's now labelled as ALT.NET practises such as
Dependency Injection containers, NHibernate, TDD andDDD . These
practises really resonated with me and since I was leading the
development of a new product I was a in good position to get to grips
with some of them (I still have trouble with test first development)
with mixed results (another post).
Coming
back to NZ and slotting into my old position I started with a lot of
enthusiasm for bringing my team "into the light" and sharing what I
thought was a better way to build applications. Our company is
marketing services based so the web sites we build can vary from the
small brochure sites up to fully integrated e-commerce applications
(very very bespoke). In hallway discussions with other programmers I
talked about some of what I had learnt and encountered mixed reactions.
The
overall impressions I received were that since our team had not
encountered some of the pain that these patterns solve then their
perceived value was lessened. I also feel some of the pain our team has
felt could be caused by these but attributed elsewhere (the functional
spec is always a tempting scapegoat).
Our
client's domains do not have huge dramatic shifts (I can only think of
one counter example) so the pain of tight coupling isn't as strong.
Without having to develop different implementations of services for
unit testing or having the domain implement core service interfaces
lessens the pain of not having dependency injection.
While
I still believed that these practises could helpful for us to use I
needed to think differently about they should be approached and the
seminal question. What to do when you encounter the solution before experiencing the pain of the problem?
In practise we do this all the time, we build our
solutions on top of other solutions, we use frameworks, libraries and
patterns, all proven solution for time old problems, we certainly don't
reinvent the wheel every time.
I'm finding
now there needs to be a bit of mix, the pain needs to be there, but
only in small doses. Create the problem yourself, show a bit of pain,
and then "solve it".
A good example is
right now I'm building some simple content management capabilities into
our core framework. Part of which is some routing based off the newMVC
Routing engine (another post). Due to the pages (and the page
repository) being part of the domain my core services are programmed
against interfaces (IPage and IPageRepository). Obviously these need use so we have a simple "RepositoryLocator"
as this pattern of usage grows and starts to become unwieldy I'll
introduce a container such as Windsor or Unity to reduce the pain.
In
short, I think some developers really need to encounter a problem
before the value of the solution is perceived, but if we can do this in
a controlled fashion then everyone wins.