• Unity整合Asp.Net MVC


      先来看一下我们的解决方案

      我们建立Yubay.Models项目,

    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Yubay.Models.Data
    {
        public class YubayDbContext : DbContext
        {
            public YubayDbContext() : base("YubayConnection")
            {
    
            }
    
            public DbSet<Category> Category { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                Database.CreateIfNotExists();
    
                base.OnModelCreating(modelBuilder);
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Yubay.Models
    {
        [Table("Category")]
        public partial class Category
        {
            public int Id { get; set; }
    
            [StringLength(100)]
            public string Code { get; set; }
    
            [StringLength(100)]
            public string ParentCode { get; set; }
    
            public int? CategoryLevel { get; set; }
    
            [StringLength(50)]
            public string Name { get; set; }
    
            [StringLength(1000)]
            public string Url { get; set; }
    
            public int? State { get; set; }
        }
    }

      接着再建立Yubay.Service项目

    using System;
    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using System.Threading.Tasks;
    using Yubay.Core.Models;
    
    namespace Yubay.Service
    {
        public interface IBaseService : IDisposable
        {
            /// <summary>
            /// 根据id查询实体
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            T Find<T>(int id) where T : class;
    
            /// <summary>
            /// 提供对单表的查询,
            /// </summary>
            /// <returns>IQueryable类型集合</returns>
            IQueryable<T> Set<T>() where T : class;
    
            /// <summary>
            /// 查询
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="funcWhere"></param>
            /// <returns></returns>
            IQueryable<T> Query<T>(Expression<Func<T, bool>> funcWhere) where T : class;
    
            /// <summary>
            /// 分页查询
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <typeparam name="S"></typeparam>
            /// <param name="funcWhere"></param>
            /// <param name="pageSize"></param>
            /// <param name="pageIndex"></param>
            /// <param name="funcOrderby"></param>
            /// <param name="isAsc"></param>
            /// <returns></returns>
            PageResult<T> QueryPage<T, S>(Expression<Func<T, bool>> funcWhere, int pageSize, int pageIndex, Expression<Func<T, S>> funcOrderby, bool isAsc = true) where T : class;
    
            /// <summary>
            /// 新增数据,即时Commit
            /// </summary>
            /// <param name="t"></param>
            /// <returns>返回带主键的实体</returns>
            T Insert<T>(T t) where T : class;
    
            /// <summary>
            /// 新增数据,即时Commit
            /// 多条sql 一个连接,事务插入
            /// </summary>
            /// <param name="tList"></param>
            /// <returns>返回带主键的集合</returns>
            IEnumerable<T> Insert<T>(IEnumerable<T> tList) where T : class;
    
            /// <summary>
            /// 更新数据,即时Commit
            /// </summary>
            /// <param name="t"></param>
            void Update<T>(T t) where T : class;
    
            /// <summary>
            /// 更新数据,即时Commit
            /// </summary>
            /// <param name="tList"></param>
            void Update<T>(IEnumerable<T> tList) where T : class;
    
            /// <summary>
            /// 根据主键删除数据,即时Commit
            /// </summary>
            /// <param name="t"></param>
            void Delete<T>(int Id) where T : class;
    
            /// <summary>
            /// 删除数据,即时Commit
            /// </summary>
            /// <param name="t"></param>
            void Delete<T>(T t) where T : class;
    
            /// <summary>
            /// 删除数据,即时Commit
            /// </summary>
            /// <param name="tList"></param>
            void Delete<T>(IEnumerable<T> tList) where T : class;
    
            /// <summary>
            /// 立即保存全部修改
            /// </summary>
            void Commit();
    
            /// <summary>
            /// 执行sql 返回集合
            /// </summary>
            /// <param name="sql"></param>
            /// <param name="parameters"></param>
            /// <returns></returns>
            IQueryable<T> ExcuteQuery<T>(string sql, SqlParameter[] parameters) where T : class;
    
            /// <summary>
            /// 执行sql,无返回
            /// </summary>
            /// <param name="sql"></param>
            /// <param name="parameters"></param>
            void Excute<T>(string sql, SqlParameter[] parameters) where T : class;
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using System.Threading.Tasks;
    using Yubay.Core.Models;
    
    namespace Yubay.Service
    {
       
        public class BaseService : IBaseService
        {
            #region Identity
            protected DbContext Context { get; private set; }
            /// <summary>
            /// 构造函数注入
            /// </summary>
            /// <param name="context"></param>
            public BaseService(DbContext context)
            {
                this.Context = context;
            }
            #endregion Identity
    
            public T Insert<T>(T t) where T : class
            {
                this.Context.Set<T>().Add(t);
                this.Commit();
                return t;
            }
    
            public IEnumerable<T> Insert<T>(IEnumerable<T> tList) where T : class
            {
                this.Context.Set<T>().AddRange(tList);
                this.Commit();//一个链接  多个sql
                return tList;
            }
    
            #region Query
            public T Find<T>(int id) where T : class
            {
                return this.Context.Set<T>().Find(id);
            }
    
            /// <summary>
            /// 不应该暴露给上端使用者
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <returns></returns>
            public IQueryable<T> Set<T>() where T : class
            {
                return this.Context.Set<T>();
            }
            /// <summary>
            /// 这才是合理的做法,上端给条件,这里查询
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="funcWhere"></param>
            /// <returns></returns>
            public IQueryable<T> Query<T>(Expression<Func<T, bool>> funcWhere) where T : class
            {
                return this.Context.Set<T>().Where<T>(funcWhere);
            }
    
            public PageResult<T> QueryPage<T, S>(Expression<Func<T, bool>> funcWhere, int pageSize, int pageIndex, Expression<Func<T, S>> funcOrderby, bool isAsc = true) where T : class
            {
                var list = this.Set<T>();
                if (funcWhere != null)
                {
                    list = list.Where<T>(funcWhere);
                }
                if (isAsc)
                {
                    list = list.OrderBy(funcOrderby);
                }
                else
                {
                    list = list.OrderByDescending(funcOrderby);
                }
                PageResult<T> result = new PageResult<T>()
                {
                    DataList = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(),
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    TotalCount = this.Context.Set<T>().Count(funcWhere)
                };
                return result;
            }
            #endregion
    
            /// <summary>
            /// 是没有实现查询,直接更新的
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="t"></param>
            public void Update<T>(T t) where T : class
            {
                if (t == null) throw new Exception("t is null");
    
                this.Context.Set<T>().Attach(t);//将数据附加到上下文,支持实体修改和新实体,重置为UnChanged
                this.Context.Entry<T>(t).State = EntityState.Modified;
                this.Commit();//保存 然后重置为UnChanged
            }
           
    
            public void Update<T>(IEnumerable<T> tList) where T : class
            {
                foreach (var t in tList)
                {
                    this.Context.Set<T>().Attach(t);
                    this.Context.Entry<T>(t).State = EntityState.Modified;
                }
                this.Commit();
            }
    
            /// <summary>
            /// 先附加 再删除
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="t"></param>
            public void Delete<T>(T t) where T : class
            {
                if (t == null) throw new Exception("t is null");
                this.Context.Set<T>().Attach(t);
                this.Context.Set<T>().Remove(t);
                this.Commit();
            }
    
            /// <summary>
            /// 还可以增加非即时commit版本的,
            /// 做成protected
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="Id"></param>
            public void Delete<T>(int Id) where T : class
            {
                T t = this.Find<T>(Id);//也可以附加
                if (t == null) throw new Exception("t is null");
                this.Context.Set<T>().Remove(t);
                this.Commit();
            }
    
            public void Delete<T>(IEnumerable<T> tList) where T : class
            {
                foreach (var t in tList)
                {
                    this.Context.Set<T>().Attach(t);
                }
                this.Context.Set<T>().RemoveRange(tList);
                this.Commit();
            }
    
    
            public void Commit()
            {
                this.Context.SaveChanges();
            }
    
            public IQueryable<T> ExcuteQuery<T>(string sql, SqlParameter[] parameters) where T : class
            {
                return this.Context.Database.SqlQuery<T>(sql, parameters).AsQueryable();
            }
    
            public void Excute<T>(string sql, SqlParameter[] parameters) where T : class
            {
                DbContextTransaction trans = null;
                try
                {
                    trans = this.Context.Database.BeginTransaction();
                    this.Context.Database.ExecuteSqlCommand(sql, parameters);
                    trans.Commit();
                }
                catch (Exception ex)
                {
                    if (trans != null)
                        trans.Rollback();
                    throw ex;
                }
            }
    
            public virtual void Dispose()
            {
                if (this.Context != null)
                {
                    this.Context.Dispose();
                }
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Yubay.Models;
    
    namespace Yubay.Service
    {
        public interface ICategoryService : IBaseService
        {
            #region Query
            /// <summary>
            /// 用code获取当前类及其全部子孙类别的id
            /// </summary>
            /// <param name="code"></param>
            /// <returns></returns>
            IEnumerable<int> GetDescendantsIdList(string code);
    
            /// <summary>
            /// 根据类别编码找子类别集合  找一级类用默认code  root
            /// </summary>
            /// <param name="code"></param>
            /// <returns></returns>
            IEnumerable<Category> GetChildList(string code = "root");
    
            /// <summary>
            /// 查询并缓存全部的类别数据
            /// 类别数据一般是不变化的
            /// </summary>
            /// <returns></returns>
            List<Category> CacheAllCategory();
            #endregion Query
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Yubay.Core.Caching;
    using Yubay.Models;
    
    namespace Yubay.Service
    {
        public class CategoryService : BaseService, ICategoryService
        {
            #region Identity
            private DbSet<Category> _CategorySet = null;
    
            public CategoryService(DbContext dbContext)
                : base(dbContext)
            {
                this._CategorySet = base.Context.Set<Category>();
            }
            #endregion Identity
    
            #region Query
            /// <summary>
            /// 用code获取当前类及其全部子孙类别的id
            /// </summary>
            /// <param name="code"></param>
            /// <returns></returns>
            public IEnumerable<int> GetDescendantsIdList(string code)
            {
                return this._CategorySet.Where(c => c.Code.StartsWith(code)).Select(c => c.Id);
            }
    
            /// <summary>
            /// 根据类别编码找子类别集合  找一级类用默认code  root
            /// </summary>
            /// <param name="code"></param>
            /// <returns></returns>
            public IEnumerable<Category> GetChildList(string code = "root")
            {
                return this._CategorySet.Where(c => c.ParentCode.StartsWith(code));
            }
    
            /// <summary>
            /// 查询并缓存全部数据
            /// </summary>
            /// <returns></returns>
            public List<Category> CacheAllCategory()
            {
                return CacheManager.Get<List<Category>>("AllCategory", () => this._CategorySet.ToList());
            }
            #endregion Query
        }
    }

      接着再创建Yubay.Core项目,里面主要的两个类

    using Microsoft.Practices.Unity.Configuration;
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Unity;
    
    namespace Yubay.Core.IOC
    {
        /// <summary>
        /// 依赖注入工厂
        /// </summary>
        public class DIFactory
        {
            private static object _SyncHelper = new object();
            private static Dictionary<string, IUnityContainer> _UnityContainerDictionary = new Dictionary<string, IUnityContainer>();
    
            /// <summary>
            /// 根据containerName获取指定的container
            /// </summary>
            /// <param name="containerName">配置的containerName,默认为defaultContainer</param>
            /// <returns></returns>
            public static IUnityContainer GetContainer(string containerName = "unityContainer")
            {
                if (!_UnityContainerDictionary.ContainsKey(containerName))
                {
                    lock (_SyncHelper)
                    {
                        if (!_UnityContainerDictionary.ContainsKey(containerName))
                        {
                            //配置UnityContainer
                            IUnityContainer container = new UnityContainer();
                            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
                            fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "config\unity.config");
                            Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
                            UnityConfigurationSection configSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
                            configSection.Configure(container, containerName);
    
                            _UnityContainerDictionary.Add(containerName, container);
                        }
                    }
                }
                return _UnityContainerDictionary[containerName];
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web.Mvc;
    using System.Web.Routing;
    using Unity;
    
    namespace Yubay.Core.IOC
    {
        /// <summary>
        /// 自定义的控制器实例化工厂
        /// </summary>
        public class UnityControllerFactory : DefaultControllerFactory
        {
            private IUnityContainer UnityContainer
            {
                get
                {
                    return DIFactory.GetContainer();
                }
            }
    
            /// <summary>
            /// 创建控制器对象
            /// </summary>
            /// <param name="requestContext"></param>
            /// <param name="controllerType"></param>
            /// <returns></returns>
            protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
            {
                if (null == controllerType)
                {
                    return null;
                }
                IController controller = (IController)this.UnityContainer.Resolve(controllerType);
                return controller;
            }
            /// <summary>
            /// 释放
            /// </summary>
            /// <param name="controller"></param>
            public override void ReleaseController(IController controller)
            {
                //释放对象
                base.ReleaseController(controller);//
            }
        }
    }

      最后在MVC项目里面配置unity.config

    <configuration>
      <configSections>
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
      </configSections>
      <unity>
        <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
        <containers>
          <container name="unityContainer">
            <extension type="Interception"/>
            <register type="System.Data.Entity.DbContext, EntityFramework" mapTo="Yubay.Models.Data.YubayDbContext, Yubay.Models"/>
            <register type="Yubay.Service.IBaseService,Yubay.Service" mapTo="Yubay.Service.BaseService, Yubay.Service"/>
            <register type="Yubay.Service.ICategoryService,Yubay.Service" mapTo="Yubay.Service.CategoryService, Yubay.Service"/>
          </container>
    
          <container name="unityContainerGeneric">
            <register type="System.Data.Entity.DbContext, EntityFramework" mapTo="Yubay.Models.Data.YubayDbContext, Yubay.Models"/>
            <register type="Yubay.Service.IBaseService`1,Yubay.Service" mapTo="Yubay.Service.BaseService`1, Yubay.Service"/>
            <register type="Yubay.Service.ICategoryService,Ruanmou.Yubay.Service" mapTo="Yubay.Service.CategoryService, Yubay.Service"/>
          </container>
        </containers>
      </unity>
    </configuration>

      那么这时候如何把Unity整合到MVC呢?我们知道http请求管道中,激活Controller的时候有一个DefaultControllerFactory,我们可以通过重写它的方法来实现,在Application_Start中使用下面的语句替换掉默认的DefaultControllerFactory。

     ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory());//替换默认的控制器工厂

      至此就将Unity整合到MVC中了。

  • 相关阅读:
    exceljs的使用
    解决ios下的微信打开的页面背景音乐无法自动播放
    js 给定日期转为星期几
    获取地址栏参数
    解决浏览器缓存 或 刷新URL地址
    计算两个日期之间的天数
    获取当前日期的前后N天日期的方法
    将一下 prototype 是什么东西,原型链的理解,什么时候用 prototype
    apply和 call 什么含义,什么区别?什么时候用
    高效Web开发的10个jQuery代码片段
  • 原文地址:https://www.cnblogs.com/jesen1315/p/11059728.html
Copyright © 2020-2023  润新知