30
2016
08

.Net框架搭建之2、SQL Server MEF依赖注入 MVC Repository框架_part2


EFRepositoryBase.cs

using InjectExample.Model.ViewModel;
/* ==============================================================================
 * 功能描述:EFRepositoryBase  
 * 创 建 者:蒲奎民
 * 创建日期:2016-08-29 10:56:35
 * CLR Version :4.0.30319.42000
 * ==============================================================================*/
using System;
using System.Collections.Generic;
using System.Composition;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using EntityFramework.Extensions;
namespace InjectExample.Component
{
    /// <summary>
    ///     EntityFramework仓储操作基类
    /// </summary>
    /// <typeparam name="TEntity">动态实体类型</typeparam>
    public abstract class EfRepositoryBase<TEntity> : IRepository<TEntity> where TEntity : class //EntityBase<TKey>
    {
        #region 属性
        /// <summary>
        ///     获取 仓储上下文的实例
        /// </summary>
        [Import]
        public IUnitOfWork UnitOfWork { get; set; }
        /// <summary>
        ///     获取 EntityFramework的数据仓储上下文
        /// </summary>
        protected UnitOfWorkContextBase EfContext
        {
            get
            {
                if (UnitOfWork is UnitOfWorkContextBase)
                {
                    return UnitOfWork as UnitOfWorkContextBase;
                }
                return null;
                // throw new DataAccessException(string.Format("数据仓储上下文对象类型不正确,应为UnitOfWorkContextBase,实际为 {0}", UnitOfWork.GetType().Name));
            }
        }
        /// <summary>
        ///  获取 当前实体的查询数据集,不跟踪状态
        /// </summary>
        public virtual IQueryable<TEntity> Entities
        {
            get { return EfContext.Set<TEntity>().AsNoTracking(); }
        }
        /// <summary>
        /// 获取 当前实体的查询数据集,有跟踪状态
        /// </summary>
        public virtual IQueryable<TEntity> Table
        {
            get { return EfContext.Set<TEntity>(); }
        }
        #endregion
        #region 公共方法
        /// <summary>
        ///     插入实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Insert(TEntity entity, bool isSave = true)
        {
            PublicHelper.CheckArgument(entity, "entity");
            EfContext.RegisterNew(entity);
            return isSave ? EfContext.Commit() : 0;
        }
        /// <summary>
        ///     批量插入实体记录集合
        /// </summary>
        /// <param name="entities"> 实体记录集合 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Insert(IEnumerable<TEntity> entities, bool isSave = true)
        {
            PublicHelper.CheckArgument(entities, "entities");
            EfContext.RegisterNew(entities);
            return isSave ? EfContext.Commit() : 0;
        }
        ///// <summary>
        /////     删除指定编号的记录
        ///// </summary>
        ///// <param name="id"> 实体记录编号 </param>
        ///// <param name="isSave"> 是否执行保存 </param>
        ///// <returns> 操作影响的行数 </returns>
        //public virtual int Delete(object id, bool isSave = true)
        //{
        //    PublicHelper.CheckArgument(id, "id");
        //    TEntity entity = EFContext.Set<TEntity>().Find(id);
        //    return entity != null ? Delete(entity, isSave) : 0;
        //}
        /// <summary>
        ///     删除实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Delete(TEntity entity, bool isSave = true)
        {
            PublicHelper.CheckArgument(entity, "entity");
            EfContext.RegisterDeleted<TEntity>(entity);
            return isSave ? EfContext.Commit() : 0;
        }
        /// <summary>
        ///     删除实体记录集合
        /// </summary>
        /// <param name="entities"> 实体记录集合 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Delete(IEnumerable<TEntity> entities, bool isSave = true)
        {
            PublicHelper.CheckArgument(entities, "entities");
            EfContext.RegisterDeleted<TEntity>(entities);
            return isSave ? EfContext.Commit() : 0;
        }
        /// <summary>
        ///     删除所有符合特定表达式的数据
        /// </summary>
        /// <param name="predicate"> 查询条件谓语表达式 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Delete(Expression<Func<TEntity, bool>> predicate, bool isSave = true)
        {
            PublicHelper.CheckArgument(predicate, "predicate");
            List<TEntity> entities = EfContext.Set<TEntity>().Where(predicate).ToList();
            return entities.Count > 0 ? Delete(entities, isSave) : 0;
        }
        /// <summary>
        ///     更新实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Update(TEntity entity, bool isSave = true)
        {
            PublicHelper.CheckArgument(entity, "entity");
            EfContext.RegisterModified<TEntity>(entity);
            return isSave ? EfContext.Commit() : 0;
        }
        public virtual int Update(IEnumerable<TEntity> entities, bool isSave = true)
        {
            PublicHelper.CheckArgument(entities, "entities");
            EfContext.RegisterModified<TEntity>(entities);
            return isSave ? EfContext.Commit() : 0;
        }
        /// <summary>
        /// 提交更新
        /// </summary>
        /// <returns></returns>
        public virtual int Commit(bool validateOnSaveEnabled = true)
        {
            return EfContext.Commit(validateOnSaveEnabled);
        }
        /// <summary>
        ///     查找指定主键的实体记录
        /// </summary>
        /// <param name="key"> 指定主键 </param>
        /// <returns> 符合编号的记录,不存在返回null </returns>
        public virtual TEntity GetByKey(object key)
        {
            PublicHelper.CheckArgument(key, "key");
            return EfContext.Set<TEntity>().Find(key);
        }
        /// <summary>
        /// 根据条件获取单条实体数据
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public TEntity GetByFiltered(Expression<Func<TEntity, bool>> filter, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "")
        {
            var query = EfContext.Set<TEntity>().Where(filter);
            if (orderBy != null)
            {
                query = orderBy(query);
            }
            HandleInclude(ref query, includeProperties);
            return query.FirstOrDefault();
        }
        /// <summary>
        ///     删除所有符合特定表达式的数据
        /// </summary>
        /// <param name="predicate"> 查询条件谓语表达式 </param>
        /// <returns> 操作影响的行数 </returns>
        public virtual int Delete(Expression<Func<TEntity, bool>> predicate)
        {
            return Entities.Where(predicate).Delete();
        }
        /// <summary>
        /// 修改操作
        /// </summary>
        /// <param name="funWhere">查询条件-谓语表达式</param>
        /// <param name="funUpdate">实体-谓语表达式</param>
        /// <returns>操作影响的行数</returns>
        public virtual int Update(Expression<Func<TEntity, bool>> funWhere, Expression<Func<TEntity, TEntity>> funUpdate)
        {
            return Entities.Where(funWhere).Update(funUpdate);
        }
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="queryable"></param>
        /// <param name="pageInfo">分页相关信息</param>
        /// <param name="total">总记录数</param>
        /// <returns></returns>
        [Obsolete]
        public virtual IList<dynamic> GetListByPage(IQueryable<dynamic> queryable, PagingInfo pageInfo, out int total)
        {
            // 获取总数
            queryable = queryable.AsNoTracking();
            var q1 = queryable.FutureCount();
            // 获取分页的数据
            var lsitTemp = queryable.Skip(pageInfo.PageIndex).Take(pageInfo.PageSize).Future();
            // 这里会触发上面所有Future函数中的查询包装到一个连接中执行
            total = q1.Value;
            //因为已经得到结果了,这里不会再次查询
            return lsitTemp.ToList();
        }
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="filter">where条件</param>
        /// <param name="orderBy">分页信息,会返回查询后的总条数(字段RecCount)</param>
        /// <param name="pageInfo">分页信息,字段RecCount返回总条数,可以不分页,NeedPage=false即可不分页</param>
        /// <param name="includeProperties">include的关联实体s,多个用逗号隔开</param>
        /// <returns></returns>
        public IQueryable<TEntity> GetListByPage(Expression<Func<TEntity, bool>> filter, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy, PagingInfo pageInfo, string includeProperties = "")
        {
            //纠正分页参数
            pageInfo = pageInfo == null ? new PagingInfo { PageIndex = 1, PageSize = 10 } : pageInfo;
            pageInfo.PageSize = pageInfo.PageSize > 0 ? pageInfo.PageSize : 10;
            IQueryable<TEntity> query = filter != null ? Entities.Where(filter) : Entities;
            HandleInclude(ref query, includeProperties);
            pageInfo.RecCount = query.Count();
            query = orderBy != null ? orderBy(query) : query;
            return pageInfo.NeedPage ? (orderBy != null ? query.Skip((pageInfo.PageIndex - 1) * pageInfo.PageSize).Take(pageInfo.PageSize) : null) : query;
        }
        /// <summary>
        /// 执行非查询sql语句
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <param name="behavior">事务属性</param>
        /// <param name="isInsertIdentity">sql语句是否在自增字段插入值</param>
        /// <param name="tableName">操作的表名(可空)</param>
        /// <param name="parameters">参数列表</param>
        /// <returns>返回影响的行数</returns>
        public virtual int ExcuteNoQuery(string sql, TransactionalBehavior behavior = TransactionalBehavior.DoNotEnsureTransaction, bool isInsertIdentity = false, string tableName = "", params object[] parameters)
        {
            if (isInsertIdentity)
            {
                if (tableName == "") tableName = typeof(TEntity).Name;
                if (sql.TrimEnd().EndsWith(";") == false) sql = sql + ";";
                sql = "SET IDENTITY_INSERT " + tableName + " ON;" + sql + "SET IDENTITY_INSERT " + tableName + "  OFF;";
            }
            return EfContext.DbContext.Database.ExecuteSqlCommand(behavior, sql, parameters);
        }
        /// <summary>
        /// 执行查询sql语句
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="sql">sql语句</param>
        /// <param name="parameters">参数列表</param>
        /// <returns></returns>
        public virtual List<T> ExcuteQuery<T>(string sql, params object[] parameters)
        {
            return EfContext.DbContext.Database.SqlQueryWithNoLock<T>(sql, parameters).ToList();
        }
        #endregion
        private void HandleInclude(ref IQueryable<TEntity> query, string includeProperties)
        {
            if (!string.IsNullOrWhiteSpace(includeProperties))
            {
                foreach (var includeProperty in includeProperties.Split
                   (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    query = query.Include(includeProperty);
                }
            }
        }
        public bool RemoveHoldingEntityInContext(TEntity entity)
        {
            var objContext = ((IObjectContextAdapter)EfContext.DbContext).ObjectContext;
            var objSet = objContext.CreateObjectSet<TEntity>();
            var entityKey = objContext.CreateEntityKey(objSet.EntitySet.Name, entity);
            Object foundEntity;
            var exists = objContext.TryGetObjectByKey(entityKey, out foundEntity);
            if (exists)
            {
                objContext.Detach(foundEntity);
            }
            return (exists);
        }
        public void RemoveFromContext(TEntity entity)
        {
            PublicHelper.CheckArgument(entity, "entity");
            EfContext.RegisterRemove(entity);
        }
        /// <summary>
        /// 实体修改日志(不含导航属性)
        /// T 必须有主键
        /// 不建议循环调用
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public string GetEntityPropertiesChangedLog(TEntity model)
        {
            var propertiesChangedLog = string.Empty;
            var list = GetEntityPropertiesChanges(model);
            foreach (var tuple in list)
            {
                var displayName = tuple.Item1.Name;
                var displayAttribute = tuple.Item1.GetCustomAttribute(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute), false) as System.ComponentModel.DataAnnotations.DisplayAttribute;
                if (displayAttribute != null && !string.IsNullOrEmpty(displayAttribute.Name))
                {
                    displayName = displayAttribute.Name;
                }
                propertiesChangedLog += string.Format("{0}:{1}->{2};", displayName, tuple.Item2, tuple.Item3);
            }
            return propertiesChangedLog.TrimEnd(';');
        }
        public List<Tuple<PropertyInfo, string, string>> GetEntityPropertiesChanges(TEntity model)
        {
            var result = new List<Tuple<PropertyInfo, string, string>>();
            #region 修改的字段
            var detachFlag = false;
            var propertiesChangedLog = string.Empty;
            var entry = EfContext.DbContext.Entry(model);
            if (entry.State == EntityState.Detached)
            {
                detachFlag = true;
                var keyNames = ((IObjectContextAdapter)EfContext.DbContext).ObjectContext.CreateObjectSet<TEntity>().EntitySet.ElementType.KeyMembers.Select(k => k.Name);
                var propertyValues = new List<object>();
                foreach (var p in model.GetType().GetProperties().Where(m => keyNames.Contains(m.Name)).ToList())
                {
                    propertyValues.Add(p.GetValue(model));
                }
                var dbModel = EfContext.Set<TEntity>().Find(propertyValues.ToArray());
                entry = EfContext.DbContext.Entry(dbModel);
                entry.CurrentValues.SetValues(model);
            }
            foreach (var propertyName in entry.CurrentValues.PropertyNames.Where(m => entry.Property(m).IsModified).ToList())
            {
                if (propertyName.StartsWith("Modified"))
                    continue;
                var property = entry.Property(propertyName);
                var displayName = propertyName;
                var propetyInfo = model.GetType().GetProperty(propertyName);
                result.Add(new Tuple<PropertyInfo, string, string>(propetyInfo, (property.OriginalValue == null ? string.Empty : JsonUtility.ToJson(property.OriginalValue)), (property.CurrentValue == null ? string.Empty : JsonUtility.ToJson(property.CurrentValue))));
            }
            if (detachFlag)
            {
                entry.State = EntityState.Detached;
            }
            #endregion
            return result;
        }
    }
}


EFUnitOfWorkContext.cs

/* ==============================================================================
 * 功能描述:EFUnitOfWorkContext  
 * 创 建 者:蒲奎民
 * 创建日期:2016-08-29 11:02:52
 * CLR Version :4.0.30319.42000
 * ==============================================================================*/
using System;
using System.Collections.Generic;
using System.Composition;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace InjectExample.Component
{
    /// <summary>
    ///     数据单元操作类
    /// </summary>
    [Shared(Boundaries.DataConsistency)]
    [Export(typeof(IUnitOfWork))]
    public class EfUnitOfWorkContext : UnitOfWorkContextBase
    {
        //[Import]
        // private ConnectionStringHelper ConnectionStringHelper { get; set; }
        [Import]
        public Lazy<EfDbContext> EfDbContext { get; set; }
        //[Import("EFReport", typeof(DbContext))]
        //private Lazy<EfReportDbContext> EfReportDbContext { get; set; }
        /// <summary>
        ///     获取 当前使用的数据访问上下文对象
        /// </summary>
        protected override DbContext Context
        {
            get
            {
                return EfDbContext.Value;
            }
        }
    }
}


IEntityMapper.cs,公共接口

using System;
using System.Collections.Generic;
using System.Data.Entity.ModelConfiguration.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace InjectExample.Component
{
    /// <summary>
    ///     实体映射接口
    /// </summary>
    public interface IEntityMapper
    {
        /// <summary>
        ///     将当前实体映射对象注册到当前数据访问上下文实体映射配置注册器中
        /// </summary>
        /// <param name="configurations">实体映射配置注册器</param>
        void RegistTo(ConfigurationRegistrar configurations);
    }
}


IRepository.cs,公共接口

using InjectExample.Model.ViewModel;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace InjectExample.Component
{
    /// <summary>
    ///     定义仓储模型中的数据标准操作
    /// </summary>
    /// <typeparam name="TEntity">动态实体类型</typeparam>
    public interface IRepository<TEntity>// where TEntity : class
    {
        #region 属性
        /// <summary>
        ///     获取 当前实体的查询数据集
        /// </summary>
        IQueryable<TEntity> Entities { get; }
        IQueryable<TEntity> Table { get; }
        #endregion
        #region 公共方法
        /// <summary>
        ///     插入实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        int Insert(TEntity entity, bool isSave = true);
        /// <summary>
        ///     批量插入实体记录集合
        /// </summary>
        /// <param name="entities"> 实体记录集合 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        int Insert(IEnumerable<TEntity> entities, bool isSave = true);
        ///// <summary>
        /////     删除指定编号的记录
        ///// </summary>
        ///// <param name="id"> 实体记录编号 </param>
        ///// <param name="isSave"> 是否执行保存 </param>
        ///// <returns> 操作影响的行数 </returns>
        //int Delete(object id, bool isSave = true);
        /// <summary>
        ///     删除实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        int Delete(TEntity entity, bool isSave = true);
        /// <summary>
        ///     删除实体记录集合
        /// </summary>
        /// <param name="entities"> 实体记录集合 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        int Delete(IEnumerable<TEntity> entities, bool isSave = true);
        /// <summary>
        ///     删除所有符合特定表达式的数据
        /// </summary>
        /// <param name="predicate"> 查询条件谓语表达式 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        int Delete(Expression<Func<TEntity, bool>> predicate, bool isSave = true);
        /// <summary>
        ///     更新实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        int Update(TEntity entity, bool isSave = true);
        int Update(IEnumerable<TEntity> entities, bool isSave = true);
        /// <summary>
        /// 提交更新
        /// </summary>
        /// <returns></returns>
        int Commit(bool validateOnSaveEnabled = true);
        //int Update(Expression<Func<TEntity, object>> propertyExpression, TEntity entity, bool isSave = true);
        /// <summary>
        /// 使用附带新值的实体信息更新指定实体属性的值
        /// </summary>
        /// <returns>操作影响的行数</returns>
        /// <summary>
        ///     查找指定主键的实体记录(从缓存中获取)
        /// </summary>
        /// <param name="key"> 指定主键 </param>
        /// <returns> 符合编号的记录,不存在返回null </returns>
        /// 
        TEntity GetByKey(object key);
        /// <summary>
        /// 通过条件获取单条实体记录
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        TEntity GetByFiltered(Expression<Func<TEntity, bool>> filter, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "");
        /// <summary>
        ///     删除所有符合特定表达式的数据
        /// </summary>
        /// <param name="predicate"> 查询条件谓语表达式 </param>
        /// <returns> 操作影响的行数 </returns>
        int Delete(Expression<Func<TEntity, bool>> predicate);
        /// <summary>
        /// 修改操作
        /// </summary>
        /// <param name="funWhere">查询条件-谓语表达式</param>
        /// <param name="funUpdate">实体-谓语表达式</param>
        /// <returns>操作影响的行数</returns>
        int Update(Expression<Func<TEntity, bool>> funWhere, Expression<Func<TEntity, TEntity>> funUpdate);
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="source">查询集合</param>
        /// <param name="pageInfo">分页相关信息</param>
        /// <param name="total">总记录数</param>
        /// <returns></returns>
        [Obsolete]
        IList<dynamic> GetListByPage(IQueryable<dynamic> source, PagingInfo pageInfo, out int total);
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="filter">where条件</param>
        /// <param name="orderBy">分页信息,会返回查询后的总条数(字段RecCount)</param>
        /// <param name="pageInfo">分页信息,字段RecCount返回总条数,可以不分页,NeedPage=false即可不分页</param>
        /// <param name="includeProperties">include的关联实体s,多个用逗号隔开</param>
        /// <returns></returns>
        /// <returns></returns>
        IQueryable<TEntity> GetListByPage(Expression<Func<TEntity, bool>> filter, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy, PagingInfo pageInfo, string includeProperties = "");
        /// <summary>
        /// 执行非查询sql语句
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <param name="behavior">事务属性</param>
        /// <param name="isInsertIdentity">sql语句是否在自增字段插入值</param>
        /// <param name="tableName">操作的表名(可空)</param>
        /// <param name="parameters">参数列表</param>
        /// <returns>返回影响的行数</returns>
        int ExcuteNoQuery(string sql, TransactionalBehavior behavior = TransactionalBehavior.DoNotEnsureTransaction, bool isInsertIdentity = false, string tableName = "", params object[] parameters);
        List<T> ExcuteQuery<T>(string sql, params object[] parameters);
        /// <summary>
        /// 从上下文中脱离(detach)对象
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        bool RemoveHoldingEntityInContext(TEntity entity);
        /// <summary>
        /// 从上下文中移除(remove)对象
        /// </summary>
        /// <param name="entity"></param>
        void RemoveFromContext(TEntity entity);
        /// <summary>
        /// 实体修改日志(不含导航属性)
        /// T 必须有主键
        /// 不建议循环调用
        /// </summary>
        /// <returns></returns>
        string GetEntityPropertiesChangedLog(TEntity model);
        /// <summary>
        /// 获取实体属性改变内容
        /// T 必须有主键
        /// 不建议循环调用
        /// </summary>
        /// <param name="model"></param>
        /// <returns>Item1 属性,Item2原值(Json),Item3新值(Json)</returns>
        List<Tuple<PropertyInfo, string, string>> GetEntityPropertiesChanges(TEntity model);
        #endregion
    }
}


IUnitOfWork.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace InjectExample.Component
{
    /// <summary>
    ///     业务单元操作接口
    /// </summary>
    public interface IUnitOfWork
    {
        #region 属性
        /// <summary>
        ///     获取 当前单元操作是否已被提交
        /// </summary>
        bool IsCommitted { get; }
        #endregion
        #region 方法
        /// <summary>
        ///     提交当前单元操作的结果
        /// </summary>
        /// <param name="validateOnSaveEnabled">保存时是否自动验证跟踪实体</param>
        /// <returns></returns>
        int Commit(bool validateOnSaveEnabled = true);
        /// <summary>
        ///     把当前单元操作回滚成未提交状态
        /// </summary>
        void Rollback();
        #endregion
    }
}


IUnitOfWorkContext.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace InjectExample.Component
{
    /// <summary>
    ///     数据单元操作接口
    /// </summary>
    public interface IUnitOfWorkContext : IUnitOfWork, IDisposable
    {
        /// <summary>
        ///   注册一个新的对象到仓储上下文中
        /// </summary>
        /// <typeparam name="TEntity"> 要注册的类型 </typeparam>
        /// <param name="entity"> 要注册的对象 </param>
        void RegisterNew<TEntity>(TEntity entity) where TEntity : class;// EntityBase<TKey>;
        /// <summary>
        ///   批量注册多个新的对象到仓储上下文中
        /// </summary>
        /// <typeparam name="TEntity"> 要注册的类型 </typeparam>
        /// <param name="entities"> 要注册的对象集合 </param>
        void RegisterNew<TEntity>(IEnumerable<TEntity> entities) where TEntity : class;// EntityBase<TKey>;
        /// <summary>
        ///   注册一个更改的对象到仓储上下文中
        /// </summary>
        /// <typeparam name="TEntity"> 要注册的类型 </typeparam>
        /// <param name="entity"> 要注册的对象 </param>
        void RegisterModified<TEntity>(TEntity entity) where TEntity : class;// EntityBase<TKey>;
        /// <summary>
        /// 使用指定的属性表达式指定注册更改的对象到仓储上下文中
        /// </summary>
        /// <typeparam name="TEntity">要注册的类型</typeparam>
        /// <param name="propertyExpression">属性表达式,包含要更新的实体属性</param>
        /// <param name="entity">附带新值的实体信息,必须包含主键</param>
        void RegisterModified<TEntity>(Expression<Func<TEntity, object>> propertyExpression, TEntity entity)
            where TEntity : class;// EntityBase<TKey>;
        /// <summary>
        ///   注册一个删除的对象到仓储上下文中
        /// </summary>
        /// <typeparam name="TEntity"> 要注册的类型 </typeparam>
        /// <param name="entity"> 要注册的对象 </param>
        void RegisterDeleted<TEntity>(TEntity entity) where TEntity : class;// EntityBase<TKey>;
        /// <summary>
        ///   批量注册多个删除的对象到仓储上下文中
        /// </summary>
        /// <typeparam name="TEntity"> 要注册的类型 </typeparam>
        /// <param name="entities"> 要注册的对象集合 </param>
        void RegisterDeleted<TEntity>(IEnumerable<TEntity> entities) where TEntity : class;// EntityBase<TKey>;
        DataSet SqlQueryForDataSet(CommandType commandType, string sql, SqlParameter[] parameters);
    }
}

MefInjectionProvider.cs

/* ==============================================================================
 * 功能描述:MefInjectionProvider  
 * 创 建 者:蒲奎民
 * 创建日期:2016-08-29 10:17:02
 * CLR Version :4.0.30319.42000
 * 包引用 :
 * Microsoft.Composition.1.0.30
 * ==============================================================================*/
using System;
using System.Collections.Generic;
using System.Composition;
using System.Composition.Convention;
using System.Composition.Hosting;
using System.Composition.Hosting.Core;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace InjectExample.Component
{
    /// <summary>
    /// 手动调用的注入类,调用方法:MefInjectionProvider.GetExport<T>(); 一般在静态类里面用,非静态类中可以用自动注入方式使用
    /// </summary>
    public static class MefInjectionProvider
    {
        private static CompositionHost _container;
        private static ExportFactory<CompositionContext> _exportFactory;
        static MefInjectionProvider()
        {
            InitInjection();
        }
        public static Export<CompositionContext> CreateContext()
        {
            return _exportFactory.CreateExport();
        }
        public static void Test()
        {
        }
        public static T GetExport<T>()
        {
            return (T)CreateContext().Value.GetExport(typeof(T));
        }
        internal static void InitInjection()
        {
            var conventions = new ConventionBuilder();
            var configuration = new ContainerConfiguration()
                .WithDefaultConventions(conventions)
                .WithAssemblies(Configuration.DefaultAssemblies());
            _container = configuration.CreateContainer();
            var factoryContract = new CompositionContract(
                typeof(ExportFactory<CompositionContext>),
                null,
                new Dictionary<string, object> { { "SharingBoundaryNames", new[] { Boundaries.HttpRequest, Boundaries.DataConsistency, Boundaries.UserIdentity } } }
                );
            _exportFactory = (ExportFactory<CompositionContext>)_container.GetExport(factoryContract);
        }
        public static void Dispose()
        {
            if (_container != null)
            {
                _container.Dispose();
            }
        }
    }
    public static class Configuration
    {
        /// <summary>
        /// 或取应用程序 Bin 路径
        /// </summary>
        /// <param name="inWeb">是否 web 应用</param>
        /// <returns></returns>
        public static IList<Assembly> DefaultAssemblies()
        {
            var exts = new[] { "exe", "dll" };
            var dir = HttpRuntime.BinDirectory != null ? HttpRuntime.BinDirectory : AppDomain.CurrentDomain.BaseDirectory;
            var ns = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace;//获取本类的命名空间
            var nsStrs = ns.Split(new char[] { '.' });//拆分要取命名空间前缀
            var files = Directory.EnumerateFiles(dir, nsStrs[0]+"*", SearchOption.TopDirectoryOnly)
                .Where(file => exts.Any(x => file.EndsWith(x, StringComparison.OrdinalIgnoreCase)))
                .ToList();
            return files.Select(Assembly.LoadFrom).ToList();
        }
        public static ContainerConfiguration WithDefaultAssemblies(this ContainerConfiguration configuration)
        {
            configuration.WithAssemblies(DefaultAssemblies());
            return configuration;
        }
    }
    public static class Boundaries
    {
        /// <summary>
        /// The boundary within which a current HTTP request is accessible.
        /// </summary>
        public const string HttpRequest = "HttpRequest";
        /// <summary>
        /// The boundary within which a consistent view of persistent data is available.
        /// </summary>
        public const string DataConsistency = "DataConsistency";
        /// <summary>
        /// The boundary within which a single user can be identified.
        /// </summary>
        public const string UserIdentity = "UserIdentity";
    }
}

~~~接下篇~~~



版权声明:
作者:真爱无限 出处:http://www.pukuimin.top 本文为博主原创文章版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接.
« 上一篇下一篇 »

相关文章:

评论列表:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。