Я передал свой проект уровня предприятия внештатным работникам, и у меня тоже неплохая настройка. Но теперь, когда контракт закончился, и человек также перешел на новую технологию, другими словами, не желая продлевать контракт. Теперь я изучаю этот код на себе. У меня есть 2 3 года опыта работы в C# и MVC. Ниже приведено приблизительное представление о моей архитектуре приложения. Надеюсь, я изо всех сил старался отвлечь архитектурные детали приложения уровня предприятия. Пожалуйста, дайте мне знать, если вам потребуется дополнительная информация по любому из вопросов.Почему я должен использовать тип интерфейса объекта в конструкторе вместо объекта фактического класса
Все мои Entities определяются как классы C# POCO как:
public class Product : BaseEntity
{
public int ProductId { get; set; }
public string ProductName { get; set; }
}
Теперь У меня есть IDbContext вроде как:
public interface IDbContext : IDisposable
{
IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity;
}
Base Entity представляет собой частичный класс POCO, что каждый Объект POCO наследуется. Вот это класс, который реализует этот IDBContext как:
public class MyObjectContext : DbContext, IDbContext
{
public new IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity
{
return base.Set<TEntity>();
}
}
Теперь я определил IDbContextFactory, который отвечает за обеспечение DBContexts как:
public interface IDbContextFactory
{
Lazy<IDbContext> CreateDbContext();
}
класс, реализующий этот интерфейс IDBContextFactory оказывает ниже структуры :
public class MyDbContextFactory : IDbContextFactory
{
public MyDbContextFactory(string dbConnectionString)
{
_dbConnectionString = Settings.DbConnectionString;
_dbContext = CreateDbContext();
}
public IDbContext CreateDbContext()
{
IDbContext dbContext = new IDbContext(() => CreateNewContext());
return dbContext;
}
private MyObjectContext CreateNewContext()
{
return new MyObjectContext (_dbConnectionString);
}
}
Здесь IRepo шаблон входит в роль:
public partial interface IRepository<T> where T : BaseEntity
{
T GetById(object id);
}
Теперь Repository класс, реализующий этот интерфейс, как показано ниже:
public partial class EfRepository<T> : IRepository<T> where T : BaseEntity
{
private readonly Lazy<IDbContext> _dbContext;
private readonly IDbContextFactory _dbContextFactory;
private readonly Lazy<ObjectStateManager> _objectStateManager;
public EfRepository(IDbContextFactory dbContextFactory)
{
_dbContextFactory = dbContextFactory;
_dbContext= _dbContextFactory.CreateDbContext();
_objectStateManager= new Lazy<ObjectStateManager>(() => ((IObjectContextAdapter)_dbContext.Value).ObjectContext.ObjectStateManager);
}
public T GetById(object id)
{
return this.Entities.Find(id);
}
}
До сих пор мы закончили с настройкой уровня инфраструктуры для управления доступом БД. Теперь дело в том, чтобы использовать эту установку в контроллерах (как у меня прямой доступ Хранилища из контроллеров) как показано ниже:
public class CountryController: BaseController
{
private readonly Lazy<IRepository<Country>> _countryRepository;
public CountryController(Lazy<IRepository<Country>> countryRepository)
{
_countryRepository = countryRepository;
}
public Country GetCountryById(int id)
{
Country country = _countryRepository.Value.GetById(id);
if (country != null)
return country;
else
return null;
}
Надеюсь, все выше ясно. Теперь вот некоторые вопросы, которые мне нужно ответить:
1) Почему мы имеем этот слоистый поток, как, как:
IDBContext -> IDBContextFactory -> IRepository <T>
, а затем, наконец, с помощью этого IRepository в контроллерах для доступа к объектам данных. Иными словами, почему мы полагаемся на интерфейсы вместо фактических объектов класса при внедрении инжекции конструктора для контроллера страны?
2) Является ли это правильным подходом для приложения уровня предприятия, поскольку он должен быть значительно масштабируемым для будущей цели. Если есть кто-то другой, я был бы рад узнать об этом?
3) В конструкторе контроллера я использовал Lazy>, поэтому в чем цель этого Lazy и действительно ли это полезно. Если да, то каким образом?
Надеюсь, это даст вам некоторую идею: http://stackoverflow.com/questions/2026054/why-do-we-use-interface-is-it-only-for-standardization –
Выберете из полки UML-архитектуру диаграммы и проектный документ, который вы подписали с вашим субподрядчиком – xmojmr
Удалите 'Lazy' из ваших репозиториев-инъекций. Это необязательно и не должно быть частью вашего «контракта». Вы всегда можете использовать прокси-класс, который добавляет ленивость. –
Maarten