Я пытаюсь добиться разделения слоев с проектом, над которым я работаю. Идея состоит в том, что я могу использовать любую функцию, которую веб-сайт имеет и модулировать. Например, если вы возьмете что-то вроде новостей и хотите добавить эту функцию на сайт, то в коде вам просто нужно будет импортировать службу новостей, модели, слой данных и т. Д. Все импортируются вместе с ним.Расширение DbContext из другого проекта
Обратите внимание, что я использую Ninject как часть проекта для впрыскивания зависимостей, поэтому мне не нужно ссылаться на конкретные классы, я только ссылаюсь на контракты.
У меня есть основной проект и слой данных, как например:
public class MainDbContext : CustomIdentityDbContext, IMainDbContext
{
}
Как вы можете видеть, что расширяет CustomIdentityDbContext, которое выглядит следующим образом:
public class CustomIdentityDbContext : IdentityDbContext<CustomUser>, ICustomIdentityDbContext
{
public CustomIdentityDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaim");
modelBuilder.Entity<IdentityUserRole>().ToTable("UserRole");
modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogin");
modelBuilder.Entity<IdentityRole>().ToTable("Role");
modelBuilder.Entity<AzularisUser>().ToTable("User");
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
public static DbContext Create()
{
return new CustomIdentityDbContext();
}
}
Моя проблема заключается в том, что мне нужно иметь таблицу новостей, а затем мне нужен EF6 для сопоставления этой таблицы, как и для Identity. Я не могу понять, как создать эти отношения. Как добавить DbSet<News> News { get; set; }
в мой MainDbContext без необходимости писать эту строку там и ссылаться на объект новостей. Поэтому я пытаюсь добиться его динамического добавления в мой класс MainDbContext в тот момент, когда я ссылаюсь на свою службу, поскольку эта служба будет запускать все остальные классы в создание себя через ninject и привязку.
Другими словами, слой данных для новостей необходимо внедрить в MainDbContext без MainDbContext, зная об этом в своих ссылках. Что-то вроде этого возможно? Если да, то как мне это достичь?
Вот что я пробовал:
public class NewsDbContext : DbContext, INewsDbContext
{
public DbSet<News> News { get; set; }
public NewsDbContext() : base("DefaultConnection") { }
public IEnumerable<INews> QueryNews()
{
return News;
}
}
Приведенный выше код компилируется и работает, однако, он не создает таблицу и когда я пытаюсь запросить его или вставить запись, она будет ломаться в виде таблицы не существует. Я не совсем уверен, как это сделать, и у меня много идей. Что-то вроде этого возможно?
EDIT:
я понял, что не может быть объяснено себя должным образом. Дай мне попробовать снова. У меня многослойная структура. У меня есть данные о службах, данных, доменах и DTO. Эти 4 слоя составляют плагин. Вдобавок к этим 4 слоям, у меня есть еще 4, которые являются интерфейсами этих слоев, так что, другими словами, контракты. Я использую Ninject для привязки моих контрактов к уровням реализации, так что основной проект никогда не ссылается на уровни реализации в проекте. По этой причине я пытаюсь подключить слой данных к слою данных основного проекта, без основного слоя данных проекта, фактически ссылающегося на слой данных плагина. Проблема в том, что плагин будет иметь свои собственные таблицы. Я бы хотел, чтобы эти таблицы автоматически создавались с EF6 при первом запуске проекта.
Мой главный проект также разделен так же, как плагин, он имеет все 4 слоя плюс уровень менеджера. Менеджер представляет собой набор сервисов и не служит никакой другой цели, он просто создает их на основе контракта с помощью Ninject. Ядро проекта содержит все представления, скрипты и файлы css, но он ссылается на интерфейс менеджера. С ninject я создаю экземпляр менеджера. Менеджер снова имеет все ссылки на контракты, а с помощью ninject он создает экземпляры этих контрактов. Службы, ссылающиеся на контракты уровня данных и уровня данных, будут запрашивать информацию и возвращать результаты службе, которая будет передана обратно контроллеру. Надеюсь, это объясняет мою структуру немного лучше.При таком подходе я пытаюсь создать trully модульный проект, где вы можете поменять местами реализацию dll и продолжить работу над проектом, не перекомпилировать всю черную вещь. Я могу иметь две полностью раздельные функции на 2 dll, но пока они реализуют один и тот же контракт, веб-сайт должен работать независимо от того, какая у него dll в своей папке.
Все, что я только что описал, работает, за исключением того, что оно работает с EF6. У меня очень похожая структура с DAPPER, и там все это хорошо и денди, когда вы пишете свой собственный запрос, и поэтому у меня не было проблем. Я пытаюсь воспроизвести это с помощью EF6. Итак, еще раз, мой вопрос: как мне получить EF6 для создания таблиц, как добавить их динамически, когда единственное, на что ссылается, - это интерфейс службы. Может быть, интерфейс может иметь функцию MapTables, но опять же я не уверен, как выполнить динамическое добавление к EF6.
Идея, которая у меня была, и я не уверен, что это может работать, и как я это сделаю, но что, если я передаю контекст БД как тип, а не расширяю его?
Обычно нужно, чтобы 'NewsDbContext' был подклассом' CustomIdentityDbContext'. Но если я правильно вас понимаю, вы хотите, чтобы сборка, содержащая «Новости», была независимой от «базовой» сборки. Другими словами, веб-приложение должно иметь возможность импортировать базовую сборку и любую другую сборку, и они должны каким-то образом быть объединены в один слой данных. Это верно? –
@GertArnold Да, я надеюсь объединить их в один слой данных. Веб-приложение должно иметь возможность импортировать сборку новостей и использовать ее через службу. – Bojan
Большой вопрос: * who * (какая сборка) знает, какие классы должны быть частью модели класса Entity Framework? –