Jas*_*son 17 c# architecture abstraction design-patterns entity-framework-4.1
首先,我认为这样做有些荒谬,但是我团队的其他成员坚持认为,除了"我认为这是愚蠢的"之外,我无法提出反对它的好论据......
我们要做的是创建一个完全抽象的数据层,然后具有该数据层的各种实现.很简单吧?输入实体框架4.1 ...
我们的最终目标是程序员(我尽力只留在数据层)永远不希望暴露于具体的类.除了显然需要实例化工厂之外,他们只想在代码中使用接口.
我希望实现以下内容:
首先我们有所有接口的"Common"库,我们称之为"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; }
}
Run Code Online (Sandbox Code Playgroud)
从那时我们就有了一个实现库,我们称之为"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()
{
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
厂:
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; }
}
}
Run Code Online (Sandbox Code Playgroud)
语境:
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; }
}
Run Code Online (Sandbox Code Playgroud)
然后前端程序员将使用它,例如:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
所以这就是它......我希望这里的某个人能够指出我正确的方向,或者帮我解决一个好的争论,我可以回到开发团队.我看过这个网站上的其他一些文章,关于EF无法使用接口和一个回复说你无法实现IDbSet(我觉得有点好奇,如果你不能实现它,他们为什么会提供它? ?)但到目前为止无济于事.
在此先感谢您的帮助!Ĵ
Lad*_*nka 45
第一个参数是EF不能与接口一起使用.DbSet必须使用真实实体实现来定义.
第二个参数是你的实体不应该包含DbSet- 这是与上下文相关的类,你的实体应该是纯粹的依赖,除非你要实现Active记录模式.即使在这种情况下,您也绝对无法访问DbSet另一个实体中的不同实体.即使你使用set,你仍然太靠近EF,并且实体永远不会拥有访问另一个实体类型的所有实体的属性(不仅仅是那些与当前实例相关的实体).
只是DbSet在EF中说清楚它有非常特殊的含义 - 它不是一个集合.它是数据库的入口点(例如,DbSet命中数据库上的每个LINQ查询),并且它处于未在实体上公开的正常场景中.
第三个参数是每个应用程序使用一个上下文 - 每个单独工厂只有一个私有实例.除非您正在进行一些单批运行批处理,否则它绝对是错误的.
最后一个论点很简单.您需要付费才能提供功能,而不是浪费时间进行抽象,这不会给您(和您的客户)带来任何商业价值.它不是为了证明为什么你不应该创建这种抽象.这是为了证明你为什么要这样做.使用它会得到什么价值?如果你的同事无法提出具有商业价值的论据,你可以简单地去找你的产品经理并让他使用他的权力 - 他持有预算.
通常,抽象是精心设计的面向对象应用程序的一部分 - 这是正确的.但:
什么时候进行"大量"抽象是有道理的?
如果您只使用目标应用程序(主要是按需提供单一用途的应用程序或外包解决方案),则只应在必要时使用抽象.这些应用程序受成本驱动 - 目标是在最短的时间内以最低的成本提供工作解决方案.即使最终的应用程序内部不是很好,也必须实现这个目标 - 唯一重要的是应用程序是否符合要求.基于"如果......发生了什么"或"可能我们将需要......"的任何抽象都会增加虚拟(非现有)需求的成本,这些需求将永远不会发生,并且在大多数情况下与客户的初始合同不计算在内这样的额外费用.
顺便说一句.这种类型的应用程序是MS API和设计师策略的目标 - MS将使许多设计师和代码生成器创建非最佳但廉价和快速的解决方案,这些解决方案可以由技能较小且非常便宜的人创建.最后一个例子是LightSwitch.
| 归档时间: |
|
| 查看次数: |
14630 次 |
| 最近记录: |