Entity Framework data package of a layer

Recent research DDD, also downloaded some maturity to do based on DDD case studies, some of it, too mature, the way he took it anything through from the inside, such as the ByteartRetail project, which took ruthless operation on the data me some time

image

Expand look

image

image

In fact, it is clear that there is a problem, with the architectural design for the project were based on DDD, different people design projects layered, named and put inside is not the same thing, this thing looks like DDD, is purely a way of thinking, so it only various implementations from inside to find their most understandable to achieve their own way of architecture. I'm sorry, because when looking to find an example of too much, you forget to place each item, but mostly in StackOverflow inside recommended by others, you can go for a search.

The above program which implements by A.And (B) .And (C) .Or (D) in this way to dynamically generate lambda expressions, within the scope of this discussion is not Benpian, see how it is used Repository pattern and Unit of Work pattern to make the data layer,

image

Because the frame with EF, so we look directly EntityFrameworkRepository, outside of it is to use the method.

This figure I simplified some, but have a backbone, first of all, IRepository container interface defines the basic CRUD interfaces (complex queries, paging can be done on the inside)

Secondly, IUnitOfWork by the interface unit of work and thought to the data submitted by the separation operation, it sounds very deep, but the realization, however, is not the SaveChanges () in which all data manipulation, but to change the way data flag state (a IRepositoryContext defined), and finally unified by the Commit method to commit the changes. For the needs of their duties, so the incident became three simple interfaces, dealt with separately: additions and deletions to the external interface, additions and deletions to the mark motion, commit and rollback transactions , these three things

Thus, there are two classes RepositoryContext and Repository, which interface is shown above are achieved

接下来,IEntityFrameworkRepositoryContext接口主要是为了针对Entity Framework做实现,所以加了一个DbContext的属性,也仅仅只是加了一个属性。这样,EntityFrameworkRepositoryContext实现IEntityFrameworkRepositoryContext的同时,继承Repository,就拥有了对DbContext对象进行标识增删改和提交、回滚的能力了。

到此,我们再把Repository类扩展一下,用EntityFrameworkRepository来继承之,从构造函数传入上面的包含了DbContext对象的EFcontext类(接口),把标识和提交的能力都带了进来,最终一个符合unit of work模式的具有操作DbContext对象的数据层就诞生了。

 

思路搞清了,我就简化了一下,如下:

image

这一次,我把Repository变为了最终暴露的类。但是实现的时候碰到了一个难题。示例程序中,DbContext对象居然是直接在EFRepositoryContext内部直接new出来的:

?
private  readonly  ThreadLocal<ByteartRetailDbContext> localCtx = new  ThreadLocal<ByteartRetailDbContext>(() => new  ByteartRetailDbContext());

这样,上面的红字我标出了它把DbContext带进去的方式,是把dbcontext实例化了,然后整个对象变成构造函数传进去,我不行啊,这个DbContext很可能不止有一个啊,那么就只有把DbContext本身变成RepositoryContext的构造函数(而不是示例中的repositorycontext)了,然后Repository继承它。最终形成上图。

image

这种方式有一个缺点,就是最终的容器不是同其接口一一对应的,而是扩展了别的功能,结果就是在外部使用的时候必须用Repository实例,而不能用接口,以实现依赖注入(DI)的功能,管它呢,先告一段落吧

image

试用一下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//测试服务接口
public  interface  Itest
{
     string  outstirng( string  msg);
}
 
//测试服务实现
public  string  outstirng()
{
     var u = new  Repository<user>( new  myEntities()); //DbContext由此传入
     user us = u.GetEntity(m => m.id == 2);
     us.addr = "update"  + DateTime.Now.ToString( "ddfff" );
     u.Update(us);
     us = u.GetEntity(m => m.id == 1);
     u.Delete(us);
     u.Commit(); //一次提交,不提交不生效
     us = u.GetEntity(m => m.id == 2);
     return  us.addr;
}

In MVC4 project in the test, with the IOC to make SimpleInjector injection:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//注入
public  static  void  Initialize()
{
     var container = new  Container();
     InitializeContainer(container);
     container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
     container.RegisterMvcAttributeFilterProvider();
     container.Verify();
     DependencyResolver.SetResolver( new  SimpleInjectorDependencyResolver(container));
}
private  static  void  InitializeContainer(Container container)
{
     container.Register<Itest, impltest>();
}

Controller:

?
1
2
3
4
5
6
7
8
9
10
11
12
public  class  TestController : Controller
{
     Itest svr;
     public  TestController(Itest service)
     {
         svr = service;
     }
     public  string  Index()
     {
         return  svr.outstirng();
     }
}

Well get results

Reproduced in: https: //www.cnblogs.com/zhangchenliang/archive/2012/12/16/2820962.html

Guess you like

Origin blog.csdn.net/weixin_33720956/article/details/93495303