c#在客户端应用程序中管理领域实体的渐进式标识
本文关键字:实体 渐进式 标识 管理 客户端 应用程序 | 更新日期: 2023-09-27 18:07:30
我有这个问题建模我的一个实体:
- 我的实体必须有一个用户用来识别单个对象的强制ID字段
- 用户不想手动输入ID,但它必须由应用程序生成,每次递增1
- 应用程序只存在于客户端机器上,在服务器上只有db
根据1。我创建Id字段是强制性的(而不是可空的),以这种方式必须提供创建实例,但程序如何知道必须使用哪个Id ?
理想情况下,我必须查询db以获得最大id,添加1并使用此值,但如何做到这一点?为了看到它似乎是我的领域对象的问题,我想将领域层与数据访问层隔离,所以我不能直接从实体调用存储库。
可能的解决方案:
- 我看联锁。增量,但如果任何用户都可以在其客户端上创建新实例,如何使用它?
- 将逻辑移动到应用逻辑层:在那里我可以调用存储库,获取ID,创建类并调用存储库保存类。以这种方式将域逻辑(增量id是特定的用户请求)移出域层
- 在域层中定义存储库接口,在实体的构造方法中调用该接口。所有这些都与依赖注入有关,但是怎么做呢?我在引导程序中使用ninject,所有引用都是从上到下的,我如何将其还原为域层,使其调用上级层,避免服务定位器反模式(否则可以简单地在我的函数中编写NinjectKernel.Get())
- 我发现了这篇文章,它很有趣,但他以一种不好的方式使用我的解决方案(没有接口),没有将字段定义为强制性的,所以他可以创建一个新的实例,而不指定id
有更好的解决方案吗?
编辑
一些代码来更好地解释这种情况:
Public MyClass {
public int Id{get;set;}
.....
public MyClass(int id){
if(id != null)
this.Id = id;
else
throw (new ArgumentException)
.....
}
}
所以我不能做MyClass mc = new MyClass(null);
但是我需要在
在数据访问层我使用NHibernate和Uow/Repository模式
在我可以得到一个有效的ID后,我可以写
UnitOfWork.MyClassRepository.Add(mc);
还有另一种解决方案,用于一些高负载的分布式应用程序。这个想法是创建一个单独的服务(web服务)来获得一个新的ID。在内部,实现可以像这样简单:
public int GetNextId()
{
return Interlocked.Increment(ref _lastId);
}
虽然你显然必须在服务启动时从数据库中获取最后一个id。
然后,在创建实体之前,您只需让每个客户端应用程序调用此服务。
但老实说,我会从数据库生成的Id开始,或者如果可能的话使用Guids。
更新:另一种选择。为每个客户端分配一个唯一的id (int)。然后在每次需要新Id时使用内部计数器,但将其与客户端混合为ClientId * 10000 + LastId。这类似于Hi/Lo生成器
在您的域模型中,您可以创建从DB获取id的存储库。并且您必须创建使用存储库生成id的域对象的工厂。