#c# #.net #entity-framework
#c# #.net #entity-framework
Вопрос:
Я использую шаблон репозитория с интерфейсами, и я использую structuremap для сопоставления между ними.
В моем global.asax я определил:
ObjectFactory.Initialize(x =>
{
x.For<IUnitOfWorkFactory>().Use<EFUnitOfWorkFactory>();
x.For(typeof(IRepository<>)).Use(typeof(EFRepository<>)
}
);
Теперь я хочу добавить другой метод db к сущности MyEntity. Итак, я создал MyEntityRepository:
class MyEntityRepository:EFRepository<MyEntity>, IMyEntityRepository {
public void CloseCall(long callId) {
....
....
}
}
Но теперь я вынужден добавить новую строку для инициализации structuremap. У меня много подобных случаев, и количество строк при инициализации structuremap становится все больше и больше.
Кроме того, в большинстве случаев добавляется только один метод, но для добавления этого единственного метода требуется интерфейс для нового репозитория, реализация в новом файле и другая инициализация structuremap — много работы для одного метода.
Как я могу это решить?
Я делаю что-то не так?
Может быть, лучше использовать метод расширения для репозитория (если есть такое расширение для generic ..)?
Комментарии:
1. Будет
x.For(typeof(IRepository<>)).Use(typeof(EFRepository<>)
скомпилирован?2. @Bala R: Да, я уже запускаю приложение с ним.
Ответ №1:
Если у вас есть специальные интерфейсы, которые должны быть разрешены с помощью специального типа, вы всегда должны где-то написать код для инициализации этого. Если вы не хотите писать слишком много кода при инициализации вашей StructureMap, используйте абстрактный фабричный шаблон для вашего уровня DAL:
Заводской интерфейс:
public interface IDalFactory
{
IXXXRepository XXXRepository { get; }
IYYYRepository YYYRepository { get; }
}
Реализация:
public class DalFactory : IDalFactory
{
private IXXXRepository _xxxRepository;
public IXXXRepository XXXRepository
{
return _xxxRepository ?? (_xxxRepository = new XXXRepository());
}
private IYYYRepository _yyyRepository;
public IYYYRepository YYYRepository
{
return _yyyRepository ?? (_yyyRepository = new YYYRepository());
}
}
И вы инициализируете свой IoC:
ObjectFactory.Initialize(x =>
{
x.For<IUnitOfWorkFactory>().Use<EFUnitOfWorkFactory>();
x.For<IDalFactory>().Use<DalFactory>();
}
);
Специализированному коду всегда нужна где-то своя регистрация, если только вы не создадите какую-нибудь автоматическую регистрацию, которая будет искать ваши сборки с отражением и регистрировать репозитории по некоторым соглашениям об именовании.
Комментарии:
1. Я ищу способ, которым я могу добавлять новые методы в базовый репозиторий без необходимости добавлять 2 новых файла и другого редактирования файла. Я ищу более простой шаблон проектирования для расширения базового репозитория и даже иногда переопределяю его методы.
2. @Naor: Вы ищете шаблон декоратора, но все равно вам нужно написать новый класс и новый интерфейс.
Ответ №2:
На моем бизнес-уровне, где я определил созданный мной интерфейс IRepository:
public abstract class BaseRepository<T> : IRepository<T> where T : IDataEntity
{
protected IRepository<T> Repository { get; set; }
public BaseRepository()
{
Repository = ObjectFactory.GetInstance<IRepository<T>>();
}
public virtual IQueryable<T> GetQuery()
{
return Repository.GetQuery();
}
public virtual IQueryable<T> GetQuery(params Expression<Func<T, object>>[] includes)
{
return Repository.GetQuery(includes);
}
public virtual void Insert(T entity)
{
Repository.Insert(entity);
}
public virtual void Update(T entity)
{
Repository.Update(entity);
}
public virtual void Delete(T entity)
{
Repository.Delete(entity);
}
public virtual void Attach(T entity)
{
Repository.Attach(entity);
}
}
В global.asax я должен сопоставить IRepository с реализацией entity framework.
И теперь для каждого класса, который я хочу предоставить в Интернете, я должен определить:
public class MyEntityRepository: BaseRepository<MyEntity> {
....
Common queries for this entity
....
....
overrides of insert, delete and so on
}
Теперь я вообще не могу использовать BaseRepository в веб-приложении, но использую репозиторий, который принадлежит сущности. Мне также не нужно регистрировать каждое расширение репозитория в structuremap. Единственное, что я должен помнить, это не использовать напрямую EFRepository (я могу получить его с помощью карты структуры — и я должен избегать его использования).