Прежде всего, я думаю, что это несколько смешно, но другие члены моей команды настаивают на этом, и я не могу выдвинуть против этого хороший аргумент, кроме "Я думаю, что это глупо" ...
То, что мы пытаемся сделать, - это создать полностью абстрактный слой данных и затем иметь различные реализации этого уровня данных. Достаточно просто, верно? Введите Entity Framework 4.1 ...
Наша конечная цель заключается в том, чтобы программисты (я делаю все возможное, чтобы остаться только на уровне данных) никогда не хотят подвергаться воздействию конкретных классов. Они только хотят использовать интерфейсы в своем коде, за исключением очевидной необходимости создания экземпляра фабрики.
Я хочу добиться чего-то вроде следующего:
Сначала у нас есть «Общая» библиотека всех интерфейсов, мы назовем ее «Common.Data»:
public interface IEntity
{
int ID { get; set; }
}
public interface IUser : IEntity
{
int AccountID { get; set; }
string Username { get; set; }
string EmailAddress { get; set; }
IAccount Account { get; set; }
}
public interface IAccount : IEntity
{
string FirstName { get; set; }
string LastName { get; set; }
DbSet<IUser> Users { get; set; } // OR IDbSet<IUser> OR [IDbSet implementation]?
}
public interface IEntityFactory
{
DbSet<IUser> Users { get; }
DbSet<IAccount> Accounts { get; }
}
После этого у нас есть библиотека реализации, мы назовем ее «Something.Data.Imp»:
internal class User : IUser
{
public int ID { get; set; }
public string Username { get; set; }
public string EmailAddress { get; set; }
public IAccount Account { get; set; }
public class Configuration : EntityTypeConfiguration<User>
{
public Configuration() : base()
{
...
}
}
}
internal class Account : IAccount
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DbSet<IUser> Users { get; set; } // OR IDbSet<IUser> OR [IDbSet implementation]?
public class Configuration : EntityTypeConfiguration<Account>
{
public Configuration() : base()
{
...
}
}
}
Factory:
public class ImplEntityFactory : IEntityFactory
{
private ImplEntityFactory(string connectionString)
{
this.dataContext = new MyEfDbContext(connectionString);
}
private MyEfDbContext dataContext;
public static ImplEntityFactory Instance(string connectionString)
{
if(ImplEntityFactory._instance == null)
ImplEntityFactory._instance = new ImplEntityFactory(connectionString);
return ImplEntityFactory._instance;
}
private static ImplEntityFactory _instance;
public DbSet<IUser> Users // OR IDbSet<IUser> OR [IDbSet implementation]?
{
get { return dataContext.Users; }
}
public DbSet<IAccount> Accounts // OR IDbSet<IUser> OR [IDbSet implementation]?
{
get { return dataContext.Accounts; }
}
}
Контекст:
public class MyEfDataContext : DbContext
{
public MyEfDataContext(string connectionString)
: base(connectionString)
{
Database.SetInitializer<MyEfDataContext>(null);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new User.Configuration());
modelBuilder.Configurations.Add(new Account.Configuration());
base.OnModelCreating(modelBuilder);
}
public DbSet<User> Users { get; set; }
public DbSet<Account> Accounts { get; set; }
}
Тогда интерфейсные программисты будут использовать его, например:
public class UsingIt
{
public static void Main(string[] args)
{
IEntityFactory factory = new ImplEntityFactory("SQLConnectionString");
IUser user = factory.Users.Find(5);
IAccount usersAccount = user.Account;
IAccount account = factory.Accounts.Find(3);
Console.Write(account.Users.Count());
}
}
Так что, в общем-то, это ... Я надеюсь, что кто-то здесь сможет либо указать мне верное направление, либо помочь мне с хорошим аргументом, который я могу использовать в команде разработчиков. Я просматривал некоторые другие статьи на этом сайте о том, что EF не может работать с интерфейсами, и один ответ о том, что вы не можете реализовать IDbSet
(что мне кажется довольно любопытным, почему предоставить его, если вы не смогли его реализовать?) но пока безрезультатно.
Заранее спасибо за любую помощь!
J