Я бы сказал, что вы близки к репозиторию, который я использую в производственном решении для планирования ресурсов в транспортных компаниях (в том числе и с помощью NHibernate) - так что для начала вы, по моему мнению, на правильном пути. Я согласен с dbones в использовании IEnumerables / IList вместо массивов - в итоге вы будете писать .ToArray () много раз: -).
Несколько вещей, которые вы могли бы рассмотреть:
Favor Composition по наследованию - вместо того, чтобы наследовать от абстрактного репозитория - пусть он будет неабстрактным и внедряет его в 'ctor и делегирует вызовы - это делает ваш проект более устойчивым в определенных ситуациях (например, для запроса только хранилище и т. д.) Таким образом, у вас также есть возможность создать возможность создания абстрактного хранилища (это слово?) и контролировать, будет ли оно общим для всех хранилищ.
В продолжение этого пункта - вы можете захотеть изменить базовый репозиторий, чтобы он имел универсальные методы вместо наследования от универсального интерфейса:
public class Repository
{
public void Add<T>(T entity)
{
using(var session = GetSession())
using(var tx = session.BeginTransaction())
{
session.Save(entity)
//Transaction handling etc.
}
}
.... //repeat ad nasseum :-)
}
Возможно, вы захотите разрешить определенным репозиториям иметь доступ к ISession - это значительно повышает гибкость ваших запросов и контроль за быстрой / ленивой выборкой, а также вы получаете все преимущества NHibernate и т. Д. Например,
public class Repository
{
public IList<T> WrapQueryInSession<T>(Func<ISession,IList<T> query)
{
using(var session = GetSession())
using(var tx = session.BeginTransaction())
{
var items = query(session);
//Handle exceptions transacitons etc.
return items;
}
}
}
Использование:
public class MovieRepository : IMovieRepository
{
private Repository _repository;
public MovieRepository(Repository repository)
{
_repository = repository;
}
public IList<Movie> GetByYear(int year)
{
Func<ISession, IList<Movie> query = session =>
{
var query = session.CreateQuery("from Movie"); //or
var query = session.CreateCriteria("from Movie"); //or
var query = session.Linq<Movie>();
//set criteria etc.
return query.List<Movie>(); //ToList<Movie>() if you're using Linq2NHibernate
}:
return _repository.WrapQueryInSession(query);
}
}
Возможно, вы также захотите установить возвращаемое значение bool для ваших методов, если что-то пойдет не так, и, возможно, выход из IEnumerable для любых ошибок, которые будут иметь смысл в вызывающем коде.
Но в целом - это всего лишь мои лакомые кусочки, которые я добавил со временем, чтобы лучше соответствовать своему использованию - и они совершенно необязательны, просто пища для размышлений :-). Я думаю, что вы на правильном пути - я не вижу серьезных проблем в вашем коде.
Надеюсь, это имеет смысл: -)