EF和Repository

  • 实体(Entities):具备唯一ID,能够被持久化,具备业务逻辑,对应现实世界业务对象。
  • 值对象(Value objects):不具有唯一ID,由对象的属性描述,一般为内存中的临时对象,可以用来传递参数或对实体进行补充描述。
  • 工厂(Factories):主要用来创建实体,目前架构实践中一般采用IOC容器来实现工厂的功能。
  • 仓库(Repositories):用来管理实体的集合,封装持久化框架。
  • 服务(Services):为上层建筑提供可操作的接口,负责对领域对象进行调度和封装,同时可以对外提供各种形式的服务。

1.定义Context:

2.定义Context对应的Factory

通用DatabaseFactory的定义:利用反射生成Factory的实例。

get()方法返回Factory实例与Context的绑定关系。如果Context已经存在,不再重新new一个entity,使用已有entity,用于防止方法嵌套,导致两个entity不同

    public class DatabaseFactoryBase<T> : IDatabaseFactory<T> where T:DbContext,IDisposable,new()
{
private T _dataContext;
//protected Boolean _objectDisposed; protected static Func<Boolean> _funcNeedCreateInstance = null;
protected static Boolean DefaultFuncChecked = false;
protected static void CreateDefaultChecker()
{
Type tdf = typeof(IDatabaseFactory<T>);
var targetAssembly = AppDomain.CurrentDomain.GetAssemblies().Where(e => e.IsDynamic == false && e.GlobalAssemblyCache == false
&& e.FullName.Contains("NewCRM.Common")).FirstOrDefault();
if (targetAssembly == null) return;
var factoryTypeName = "NewCRM.Common.DependencyInjection.IocFactory";
var factoryType = targetAssembly.GetType(factoryTypeName);
if (factoryType!=null)
{
var instanceProp = factoryType.GetProperty("Instance", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
if (instanceProp!=null)
{
var method = instanceProp.PropertyType.GetMethod("GetRegistration", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
if (method != null)
{
var returnType = method.ReturnType;
var lsPropType = returnType.GetProperty("LifeStyle", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).PropertyType;
var peRegistration = Expression.Variable(returnType);
var boolType = typeof(Boolean);
var peResult = Expression.Variable(boolType);
var listFullExpression = new List<Expression>();
var expInitResult = Expression.Assign(peResult, Expression.Constant(false));
listFullExpression.Add(expInitResult); var instance = instanceProp.GetValue(null);
var expGetRegistration = Expression.Assign(peRegistration, Expression.Call(Expression.Constant(instance), method,Expression.Constant(tdf)));
listFullExpression.Add(expGetRegistration); var checkLifeStyle = Expression.OrElse(
Expression.Equal(peRegistration, Expression.Constant(null)),
Expression.Equal(Expression.Convert(Expression.Property(peRegistration, "LifeStyle"),typeof(Int32)), Expression.Constant(2))
);
var expAssignResult = Expression.IfThen(checkLifeStyle,
Expression.Assign(peResult, Expression.Constant(true)));
listFullExpression.Add(expAssignResult); var lbRet = Expression.Label(boolType);
listFullExpression.Add(
Expression.MakeGoto(
GotoExpressionKind.Return,
lbRet,
peResult,
boolType
)
);
listFullExpression.Add(
Expression.Label(lbRet, Expression.Default(boolType)));
var m2 = Expression.Lambda<Func<Boolean>>(
Expression.Block(new ParameterExpression[] { peRegistration, peResult }, listFullExpression)
);
var m3 = m2.Compile();
_funcNeedCreateInstance = m3;
}
} } }
public DatabaseFactoryBase()
{
//_objectDisposed = false;
} /// <summary>
/// Dispose underlying resource
/// </summary>
public virtual void ReleaseCurrentContext()
{
try
{
if (_dataContext != null /*&& !_objectDisposed*/)
{
System.Diagnostics.Debug.WriteLine(String.Format("Database Factory:Release context {0}", typeof(T).FullName)); //_objectDisposed = true;
_dataContext.Dispose();
}
}
finally
{
_dataContext = null;
} } /// <summary>
/// Dispose underlying resource
/// </summary>
public virtual void Dispose()
{
ReleaseCurrentContext();
} /// <summary>
/// Get the factory instance
/// </summary>
/// <returns>datacontext instance</returns>
public virtual IAutoDisposeDataContext<T> Get()
{
var needCreateInstance = NeedCreateInsance();
if ((!needCreateInstance || UnitTestHelper.UnitTestMode) && _dataContext != null) return new AutoDisposeDataContext<T>(_dataContext,this);
_dataContext = new T();
#if DEBUG
System.Diagnostics.Debug.WriteLine(String.Format("Database Factory:Creating context {0}", typeof(T).FullName));
#endif
return new AutoDisposeDataContext<T>(_dataContext,this);
} public virtual bool NeedCreateInsance()
{
//Type tdf = typeof(IDatabaseFactory<T>);
//var instance = IocFactory.Instance;
//var impl = instance.GetRegistration(tdf);
//Boolean needCreateInstance = false;
////if the impl is null,it use the default factory
//if (impl == null || impl.LifeStyle == IocLifeStyle.Transient)
//{
// needCreateInstance = true;
//}
//return needCreateInstance;
if (!DefaultFuncChecked)
{
CreateDefaultChecker();
DefaultFuncChecked = true;
}
if (_funcNeedCreateInstance != null) return _funcNeedCreateInstance();
return true;
}
}

定义Context与Factory的绑定关系

    public class AutoDisposeDataContext<T> : IAutoDisposeDataContext<T> where T : DbContext, new()
{
private T _dataContext;
private IDatabaseFactory<T> _databaseFactory;
public AutoDisposeDataContext(T dataContext, IDatabaseFactory<T> databaseFactory)
{
_dataContext = dataContext;
_databaseFactory = databaseFactory;
} public T Context
{
get
{
return _dataContext;
}
} public void Dispose()
{
Boolean useActualDb = false;
if (Context is DbContext)
{
var adapter = Context as IObjectContextAdapter;
if (adapter != null && adapter.ObjectContext != null) useActualDb = true;
}
if (_databaseFactory.NeedCreateInsance() && (useActualDb || !UnitTestHelper.UnitTestMode))
{
Context.Dispose();
_databaseFactory.ReleaseCurrentContext();
}
//Type tdf = typeof(IDatabaseFactory<T>);
//var instance = IocFactory.Instance;
//var impl = instance.GetRegistration(tdf);
////do not dispose object in unit test mode
//if ( (impl==null || impl.LifeStyle == IocLifeStyle.Transient) && !UnitTestHelper.UnitTestMode)
//{
// _databaseFactory.Dispose();
//}
}
}

  

  

3.每个context中的表对应的Respository的构造函数中,传入所在Context的Factory。

  Context对应的RepositoryBase

  公共RepositoryBase基类,以及其对factory的调用

  目的:各表的Respository通过Factory实现对Context中对应表的增、删、改、查……基本操作。实现的增、删、改、查……基本操作的抽象

     Respository:为Service提供服务,为其提供基本的操作。调用

     Service:针对特定的业务逻辑,调用Respository来实现对数据库的操作

  

EF、Repository、Factory、Service间关系的更多相关文章

  1. mvc项目架构分享系列之架构搭建之Repository和Service

    项目架构搭建之Repository和Service的搭建 Contents 系列一[架构概览] 0.项目简介 1.项目解决方案分层方案 2.所用到的技术 3.项目引用关系 系列二[架构搭建初步] 4. ...

  2. Spring注解@Component、@Repository、@Service、@Controller,@Autowired、@Resource用法

    一.Spring定义bean,@Component.@Repository.@Service 和 @Controller Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥 ...

  3. Spring学习使用标签来标记资源(@Component、@Repository、 @Service和@Controller)和用法(包括如何jsp正在使用)

    首先,在xml其中新增部分标有下划线的文件,容器初始化的时候需要扫描包 注意: a.     包款扫描(下划线部分)一定要加,默认是不扫描整个包.与每一包之间','开.如过具有同样的父包,那么我们能够 ...

  4. Spring中常用的注解(@Entity,@Table,@Column,@Repository,@Service)

    当项目变得比较大的时候,如何还使用hbm.xml文件来配置Hibernate实体就会变得比较复杂.这里Hibernate提供了Annotation注解方式,使得Hibernate的映射文件变得很方便管 ...

  5. Spring注解@Repository、@Service、@Controller、@Component

    继前几章所讲解的注解中: http://www.cnblogs.com/EasonJim/p/6892280.html http://www.cnblogs.com/EasonJim/p/689974 ...

  6. 关于Spring注解@Component、@Repository、@Service、@Controller @Resource、@Autowired、@Qualifier 解析

    1.Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository.@Service和 @Controller 其实这三个跟@Com ...

  7. EF里的继承映射关系TPH、TPT和TPC的讲解以及一些具体的例子

    本章节讲解EF里的继承映射关系,分为TPH.TPT.TPC.具体: 1.TPH:Table Per Hierarchy 这是EF的默认的继承映射关系:一张表存放基类和子类的所有列,自动生成的discr ...

  8. 【极力分享】[C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例【转载自https://segmentfault.com/a/1190000004152660】

      [C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例 本文我们来学习一下在Entity Framework中使用Cont ...

  9. UML(一) 类图及类间关系

    原创文章,同步发自作者个人博客,http://www.jasongj.com/uml/class_diagram/ UML类图 UML类图介绍 在UML 2.*的13种图形中,类图是使用频率最高的UM ...

随机推荐

  1. T-SQL中的十大注意事项

    转载自:http://www.cnblogs.com/CareySon/archive/2012/10/11/2719598.html 1.在生产环境中不要出现Select * 这一点我想大家已经是比 ...

  2. hashcode()和equals()的作用、区别、联系

        介绍一. hashCode()方法和equal()方法的作用其实一样,在Java里都是用来对比两个对象是否相等一致,那么equal()既然已经能实现对比的功能了,为什么还要hashCode() ...

  3. vue中两种路由跳转拼接参数

    this.$router.push({name:"Home",query:{id:1,name:2}}) // 取到路由带过来的参数 let routerParams = this ...

  4. uvloop —— 超级快的 Python 异步网络框架

    简短介绍 asyncio是遵循Python标准库的一个异步 I/O框架.在这篇文章里,我将介绍 uvloop: 可以完整替代asyncio事件循环.uvloop是用Cython写的,基于 libuv. ...

  5. (转)Elasticsearch 的坑爹事——记录一次mapping field修改过程

    Elasticsearch 的坑爹事 本文记录一次Elasticsearch mapping field修改过程 团队使用Elasticsearch做日志的分类检索分析服务,使用了类似如下的_mapp ...

  6. rsync+inotify安装配置 实时同步文件

    安装 #安装inotify 工具 [root@localhost ~]# yum install inotify-tools -y 常用命令 [root@localhost ~]# inotifywa ...

  7. unity3d-射线(Ray)

    射线Ray 射线是一个点向另外一个点发生的一条线,一旦与其他模型发生碰撞,他将停止发射.注意这条件是逻辑上的,界面上看不到. 一般使用射线判断是否发射至某个游戏对象上或者获得鼠标点击的游戏对象等. 用 ...

  8. pycharm Unresolved reference 无法引入包

    1. 问题描述: 在项目中P存在文件夹A.B.C,A有文件夹a和b,在a中引入b的一个类, a.py: from b import func1 虽然运行成功,但是在Pycharm中显示: Unreso ...

  9. 安装PHP及Memcache扩展

    安装PHP及Memcache扩展 地址:http://blog.csdn.net/poechant/article/details/6802312   1. 下载 (1)libevent 官方网页:h ...

  10. potplayer启动慢的各种奇葩原因

    此博文可能会持续更新,因为启动慢的原因各种奇葩啊 1.声卡(螃蟹卡)驱动导致的启动慢.解决方法:potplayer中,"选项"->"声音"->修改一 ...