Кажется, есть много примеров реализации шаблона репозитория для Linq to SQL. Большинство из них имеют IRepository и DI; Некоторые внедрили Единицу работы, а некоторые нет. Я попытался прочитать, так как большинство результатов, возвращаемых поисками в SO и Google в шаблонах репозитория Linq to SQL. Тем не менее, я еще не нашел полного решения.
Из моих чтений я реализовал шаблон хранилища, как показано ниже:
Я использую DI для регистрации интерфейсов, от которых зависят репозитории:
this.container.RegisterType<IConnectionStringFactory, ConnectionStringFactory>(new ContainerControlledLifetimeManager(),
new InjectionConstructor(connectionString));
this.container.RegisterType<IDataContextFactory, DataContextFactory>();
Реализация шаблона репозитория:
public interface IPrivilegeRepository : IRepository<PrivilegesEntity>
{
IList<MenuModel> GetRootMenu();
IList<MenuModel> GetChildMenu(int parentId);
}
public class PrivilegeRepository : Repository<PrivilegesEntity>, IPrivilegeRepository
{
#region IPrivilegeRepository Members
public IList<MenuModel> GetRootMenu()
{
return FindAll(menu => menu.ParentId == null)
.OrderBy(menu => menu.SortOrder)
.Select(c => EntityMapper.Privileges.ToBusinessObject(c))
.ToList();
}
public IList<MenuModel> GetChildMenu(int parentId)
{
return FindAll(menu => menu.ParentId == parentId)
.OrderBy(menu => menu.SortOrder)
.Select(menu => EntityMapper.Privileges.ToBusinessObject(menu))
.ToList();
}
#endregion
public PrivilegeRepository(IDataContextFactory dataContextFactory)
: base(dataContextFactory)
{
}
}
Общий интерфейс репозитория:
public interface IRepository<T> where T : class
{
IEnumerable<T> All();
IEnumerable<T> FindAll(Expression<Func<T, bool>> exp);
T Single(Expression<Func<T, bool>> exp);
T First(Expression<Func<T, bool>> exp);
}
Класс репозитория реализован, как показано ниже, с реализациями IRepository (не показаны) и имеет зависимость от IDataContextFactory, о которой заботится DI:
public class Repository<T> : IRepository<T> where T : class
{
public Repository(IDataContextFactory dataContextFactory)
{
this.dataContextFactory = dataContextFactory;
}
}
Репозитории используются с использованием IoC:
PrivilegeRepository repository = container.Resolve<PrivilegeRepository>();
Я возвращаю результат запросов в виде коллекции Business Object, чтобы избежать зависимости от Linq to SQL на прикладных уровнях, где я использую репозиторий. Приведенный выше сценарий прекрасно работает с моим приложением WPF, использующим шаблон MVVM. У меня есть ViewModel aks Presenter классы, которые не зависят от классов, сгенерированных Linq-SQL.
Как расширить этот шаблон, чтобы я мог сохранять данные в базе данных. Я хотел бы передать Business Objects обратно в хранилище и сохранить их. Является ли это возможным? Как я могу реализовать Unit of Work в таком сценарии.