﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>Kasi Prasad commented on Common infrastructure? Don't make me laugh</title><description>I have to agree with Oren and Colin.
  
  
Repositories need to be molded against the application their being used for. What if I don't want my repositories responsible for persisting information and want to use a separate unit of work implementation (which i do) and I instead want my repositories to be query-able. In fact that's all I really want them to do; provide the ability to find things in my domain.
</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment15</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment15</guid><pubDate>Sun, 23 Nov 2008 08:14:59 GMT</pubDate></item><item><title>Colin Jack commented on Common infrastructure? Don't make me laugh</title><description>I think the comments might be going off course, IRepository
&lt;t was just an example. The question is whether you evolve a solution for your project or try to reuse a generic solution.
&gt;</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment14</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment14</guid><pubDate>Sun, 16 Nov 2008 14:55:43 GMT</pubDate></item><item><title>Ritesh Rao commented on Common infrastructure? Don't make me laugh</title><description>Hi Oren,
  
  
I had posted some blog posts on my thoughts on implementing a Repository pattern based on the IQueryable. The beauty of using IQuerable as the uderlying base for the repository is that it further decouples the repository from infrastructure concerns, that is assuming that the underlying infrastructure provides an IQueryable implementation (something that NHibernate needs badly). Couple that with composable specifications that uses lambda expressions, that provides a lot of power.
  
  
[www.codeinsanity.com/.../...ng-repository-and.html](http://www.codeinsanity.com/2008/08/implementing-repository-and.html)  
[www.codeinsanity.com/.../...ance-and-ddd-with.html](http://www.codeinsanity.com/2008/08/persistence-ignorance-and-ddd-with.html)  
  
BTW, love your blog. Thanks!
  
  
- Ritesh
</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment13</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment13</guid><pubDate>Fri, 14 Nov 2008 15:38:24 GMT</pubDate></item><item><title>Bryan Watts commented on Common infrastructure? Don't make me laugh</title><description>And of course those should all be generic types, especially
  
  
QueryableRepository{T, TSource} :
  
  Repository{T},
  
  IQueryableRepository{T}
  
  where TSource : IQueryable{T}
</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment12</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment12</guid><pubDate>Fri, 14 Nov 2008 06:23:34 GMT</pubDate></item><item><title>Bryan Watts commented on Common infrastructure? Don't make me laugh</title><description>&gt; I usually think about IQueryable as mutable.
  
  
Linq is a functional approach to querying. Immutability is a core concept - queries are deferred and can be defined and composed without side effects.
  
  
IQueryable defines the potential to be queried - the queryee (?) determines what a query actually means.
  
  
Here is my take on IRepository (in use in personal libraries):
  
  
=== Interfaces ===
  
  
public interface IRepository
&lt;t : IEnumerable
&lt;t  
{
  
	void Save(T item);
  
  
	void Delete(T item);
  
}
  
  
public interface IQueryableRepository
&lt;t : IQueryable
&lt;t, IRepository
&lt;t  
{
  
  
}
  
  
=== Default implementations ===
  
  
public abstract class Repository
&lt;t : IRepository
&lt;t  
{
  
	#region IEnumerable
  
  
	public abstract IEnumerator
&lt;t GetEnumerator();
  
  
	IEnumerator IEnumerable.GetEnumerator()
  
	{
  
		return GetEnumerator();
  
	}
  
	#endregion
  
  
	#region IRepository
  
  
	public abstract void Save(T item);
  
  
	public abstract void Delete(T item);
  
  
	#endregion
  
}
  
  
public abstract class QueryableRepository
&lt;t,&gt;
 :
  
	Repository
&lt;t,
  
	IQueryableRepository
&lt;t  
	where TSource : IQueryable
&lt;t  
{
  
	protected QueryableRepository(TSource source)
  
	{
  
		if(source == null)
  
		{
  
				throw new ArgumentNullException("source");
  
		}
  
  
		this.Source = source;
  
	}
  
  
	#region IEnumerable
  
  
	public override IEnumerator
&lt;t GetEnumerator()
  
	{
  
		return this.Source.GetEnumerator();
  
	}
  
	#endregion
  
  
	#region IQueryable
  
  
	Type IQueryable.ElementType
  
	{
  
		get { return this.ElementType; }
  
	}
  
  
	Expression IQueryable.Expression
  
	{
  
		get { return this.Expression; }
  
	}
  
  
	IQueryProvider IQueryable.Provider
  
	{
  
		get { return this.Provider; }
  
	}
  
	#endregion
  
  
	protected TSource Source { get; private set; }
  
  
	protected Type ElementType
  
	{
  
		get { return typeof(T); }
  
	}
  
  
	protected Expression Expression
  
	{
  
		get { return this.Source.Expression; }
  
	}
  
  
	protected IQueryProvider Provider
  
	{
  
		get { return this.Source.Provider; }
  
	}
  
}
  
  
=== Linq to Sql implementation ===
  
  
public class TableRepository
&lt;tentity : QueryableRepository
&lt;tentity,&gt;
&gt; where TEntity : class
  
{
  
	#region Static
  
  
	private static Table
&lt;tentity GetTable(DataContext context)
  
	{
  
		if(context == null)
  
		{
  
			throw new ArgumentNullException("context");
  
		}
  
  
		return context.GetTable
&lt;tentity();
  
	}
  
	#endregion
  
  
	public TableRepository(DataContext context) : base(GetTable(context))
  
		{}
  
  
	#region Overrides : QueryableRepository
  
  
	public override void Save(TEntity item)
  
	{
  
		if(!this.Source.Contains(item))
  
		{
  
			this.Source.InsertOnSubmit(item);
  
		}
  
	}
  
  
	public override void Delete(TEntity item)
  
	{
  
		if(item == null)
  
		{
  
			throw new ArgumentNullException("item");
  
		}
  
  
		this.Source.DeleteOnSubmit(item);
  
	}
  
	#endregion
  
}
&gt;</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment11</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment11</guid><pubDate>Fri, 14 Nov 2008 06:20:05 GMT</pubDate></item><item><title>Rob commented on Common infrastructure? Don't make me laugh</title><description>What do you consider a good repository interface?
</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment10</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment10</guid><pubDate>Thu, 13 Nov 2008 21:32:10 GMT</pubDate></item><item><title>Colin Jack commented on Common infrastructure? Don't make me laugh</title><description>@Rob
  
I guess that example just emphasizes what Ayende is saying because I don't consider that a good repository interface, emphasizing that you need to evolve your own designs in these sorts of cases.
</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment9</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment9</guid><pubDate>Thu, 13 Nov 2008 21:09:28 GMT</pubDate></item><item><title>Ayende Rahien commented on Common infrastructure? Don't make me laugh</title><description>Hm,
  
I usually think about IQueryable as mutable.
  
I guess it doesn't have to be.
</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment8</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment8</guid><pubDate>Thu, 13 Nov 2008 14:40:34 GMT</pubDate></item><item><title>Rob commented on Common infrastructure? Don't make me laugh</title><description>I'm not sure I see what you mean.  Since repository is queryable you can build any number of queries against it.
  
  
var r = from c in CustomerRepository where c.Balance &gt; 0 select c;
  
  
or better yet, build specifications that are extension methods on queryable and in your service layer do stuff like:
  
  
return customers.ThatAreActive().WithOutstandingBalance()
  
  
</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment7</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment7</guid><pubDate>Thu, 13 Nov 2008 14:29:10 GMT</pubDate></item><item><title>Ayende Rahien commented on Common infrastructure? Don't make me laugh</title><description>Rob,
  
The problem with that is that assume that you have a single query per repository.
</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment6</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment6</guid><pubDate>Thu, 13 Nov 2008 14:20:48 GMT</pubDate></item><item><title>Rob commented on Common infrastructure? Don't make me laugh</title><description>My generic parameters got eaten in the comment above if that wasn't obvious.
  
IRepository of T : IQueryable of T
</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment5</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment5</guid><pubDate>Thu, 13 Nov 2008 14:14:59 GMT</pubDate></item><item><title>Rob commented on Common infrastructure? Don't make me laugh</title><description>If you base your repository around IQueryable then it becomes much simpler and easier to reuse.  That will be more of a possibility for you I guess when LINQ to nHibernate is a little further along.
  
  
Something like:
  
public interface IRepository
&lt;t : IQueryable
&lt;t where T : class
  
{
  
  void InsertOnSubmit(T entity);
  
  void DeleteOnSubmit(T entity);
  
}
&gt;</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment4</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment4</guid><pubDate>Thu, 13 Nov 2008 14:13:24 GMT</pubDate></item><item><title>Dave Newman commented on Common infrastructure? Don't make me laugh</title><description>Maybe the DDD style Repository is worth another look?
</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment3</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment3</guid><pubDate>Thu, 13 Nov 2008 14:01:01 GMT</pubDate></item><item><title>Colin Jack commented on Common infrastructure? Don't make me laugh</title><description>Couldn't agree more with this point and I like the technology infrastructure and application infrastructure split.
</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment2</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment2</guid><pubDate>Thu, 13 Nov 2008 08:54:51 GMT</pubDate></item><item><title>J Healy commented on Common infrastructure? Don't make me laugh</title><description>I agree somewhat with your assertion around technological vs. application infrastructure, but that whole discussion quickly starts turning around the semantics of "application" and what 'services/functionality' such an infrastructure might expose / provide. When you say: "multiple projects that aren't closely matched" - I think you are getting closer to the mark relative to such "common infrastructures" overreaching. In some sense I feel you do simply run up against a sweeping 'lowest common denominator' factor that casts a clear light on the risks of overreaching beyond a certain point.
  
  
Azure and all the other PaaS offerings are probably a pretty good indicator of that "lowest common denominator" factor at work relative to where the 'natural' boundaries lie between "technological" and "application" infrastructures. But even there I suspect any significant apps you might build atop Azure, Gears, or EC2 would in fact exhibit enough common [admin] code to constitute something one might call a "common application infrastructure". You can argue how thick or thin that stack might be, but I suspect, once recognized, most pragmatists would resue that body of code, however derisible or unclean the exercise might feel due to other sensibilities.
  
</description><link>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment1</link><guid>http://ayende.com/3693/common-infrastructure-dont-make-me-laugh#comment1</guid><pubDate>Thu, 13 Nov 2008 06:09:47 GMT</pubDate></item></channel></rss>