首页 > 学院 > 开发设计 > 正文

游刃于MVC、WCF中的Autofac

2019-11-17 01:57:02
字体:
来源:转载
供稿:网友

游刃于MVC、WCF中的Autofac

为了程序的健壮性、扩展性、可维护性,依赖抽象而不是具体实现类等等,于是我选择了Autofac依赖注入容器 就是这个工厂来降低耦合。之前买东西是自己去超市,现在呢 我需要什么东西,他们给送过来直接拿到了。

本例中将会分享

1.Autofac在Mvc的Controller控制器、Filter过滤器的使用

2.WCF中的使用

3.用Autofac来完成Unit Of Work工作单元模式 即同一个界限上下文内可以共享同一个工作单元实例。这样就可以统一提交,起到事务作用、数据统一性。一个http请求只有一个上下文实例也算是性能优化吧, 在这里只用到工作单元的一些皮毛。

Demo全貌如下

  • Autofac.DataModel 采用database first的实体数据模型
  • Autofac.Repository实体泛型的仓储模式 ,也可以简单的理解是数据层
  • Autofac.CoreService 业务逻辑处理
  • Autofac.UnitOfWork 工作单元统一提交
  • Autofac.Controllers 控制器层是从Web层把所有控制器提取出来,这里用到区域Area
  • AutoFac.Web 前端采用的是MVVM模式的knockout.js ,还有autofac的配置
  • Autofac.ViewModel 视图

  其中Repository、UnitOfWork、CoreService几者之间调用接口或对供其他层调用接口。

  从nuget获取必要的Autofac程序包 Autofac、Autofac.Configuration、Autofac.Integration.Mvc、Autofac.Integration.Wcf

各个层依赖的是接口而不是具体实现类,Autofac是个工厂可以通过编译的代码xml配置文件两种方式指定接口、实现类来完成注入实例。

这里用的是xml配置的方式,需要用到Autofac.Configuration程序集。这样做有个明显的好处:文件不需要编译;不会扰乱各层关系。为什么这么说呢?如果用代码来完成,web层就需要其他层的接口和实现类 也就是引用Repository、UnitOfWork、CoreService层,很明显web层只需要引用Autofac.Controllers 就足够了。而通过xml配置文件可以在bin目录下找到具体的程序集如:Autofac.CoreService.dll

Autoface依赖注入在MVC里实现

Global.cs    

PRotected void application_Start()        {            //创建IOC容器            AutofacRegistion.BuildMvcContainer();            AutofacRegistion.BuildWcfContainer();            AreaRegistration.RegisterAllAreas();            WebApiConfig.Register(GlobalConfiguration.Configuration);            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);            RouteConfig.RegisterRoutes(RouteTable.Routes);        }
/// <summary>    /// 依赖注入Controller、FilterAtrribute、WCF    /// </summary>    public class AutofacRegistion    {        /// <summary>        /// 创建 MVC容器(包含Filter)        /// </summary>        public static void BuildMvcContainer()        {            var builder = new ContainerBuilder();            //注册Module方法2 在Web.config中配制方式            builder.RegisterModule(new ConfigurationSettingsReader("autofacMvc"));            //加载 *.Controllers 层的控制器,否则无法在其他层控制器构造注入,只能在web层注入            Assembly[] asm = GetAllAssembly("*.Controllers.dll").ToArray();            builder.RegisterAssemblyTypes(asm);            //注册仓储            Assembly[] asmRepository = GetAllAssembly("*.Repository.dll").ToArray();            builder.RegisterAssemblyTypes(asmRepository)               .Where(t => t.Name.EndsWith("Repository"))               .AsImplementedInterfaces();

        //注入逻辑层也可以通过配置实现         //Assembly[] asmRepositoryService = GetAllAssembly("*.CoreService.dll").ToArray();         //builder.RegisterAssemblyTypes(asmRepositoryService).AsImplementedInterfaces();

            builder.RegisterControllers(Assembly.GetExecutingAssembly());            builder.RegisterModelBinders(Assembly.GetExecutingAssembly());            builder.RegisterModelBinderProvider();                        //注册过滤器             builder.RegisterFilterProvider();            builder.RegisterType<OperateAttribute>().PropertiesAutowired();            builder.RegisterControllers(typeof(MvcApplication).Assembly);            var container = builder.Build();            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));        }        /// <summary>        ///创建WCF的容器,不存放Controller、Filter        /// </summary>        public static void BuildWcfContainer()        {            var builder = new ContainerBuilder();            builder.RegisterModule(new ConfigurationSettingsReader("autofacWcf"));            builder.RegisterModelBinders(Assembly.GetExecutingAssembly());            builder.RegisterModelBinderProvider();            var container = builder.Build();            //WCF IOC容器            AutofacHostFactory.Container = container;            //DependencyResolver.SetResolver(new AutofacDependencyResolver(container));        }        #region 加载程序集        public static List<Assembly> GetAllAssembly(string dllName)        {            List<string> pluginpath = FindPlugin(dllName);            var list = new List<Assembly>();            foreach (string filename in pluginpath)            {                try                {                    string asmname = Path.GetFileNameWithoutExtension(filename);                    if (asmname != string.Empty)                    {                        Assembly asm = Assembly.LoadFrom(filename);                        list.Add(asm);                    }                }                catch (Exception ex)                {                    Console.Write(ex.Message);                }            }            return list;        }        //查找所有插件的路径        private static List<string> FindPlugin(string dllName)        {            List<string> pluginpath = new List<string>();                           string path = AppDomain.CurrentDomain.BaseDirectory;                string dir = Path.Combine(path, "bin");                string[] dllList = Directory.GetFiles(dir, dllName);                if (dllList.Length > 0)                {                    pluginpath.AddRange(dllList.Select(item => Path.Combine(dir, item.Substring(dir.Length + 1))));                }            return pluginpath;        }        #endregion    }

说明:

1 web.config还需要配置 globlal代码中对应的【autofacMvc】和【autofacWcf】节点

2 反射*.Controllers.dll获取Autofac.Controllers程序集,实现注入

3反射*.Repository.dll获取 Autofac.Repository程序集以'Repository'结尾的类的实例注入到它所继承的接口,这个就不需要在xml中配置

4filter的注入和controller的注入方式不一样

5 MVC和WCF注入实例分别存到两个容器中。这就用到Autofac.Integration.Mvc、Autofac.Integration.Wcf两个程序集。WCF注入的容器中不需要Controller、Filter,就可以把相关的反射和注册去掉了。

web.config

<configSections>    <!-- autofac配置-->    <section name="autofacMvc" type="Autofac.Configuration.SectionHandler, Autofac.Configuration" />    <section name="autofacWcf" type="Autofac.Configuration.SectionHandler, Autofac.Configuration" />  </configSections>  <autofacMvc>    <files>      <file name="configs/CoreService.config" section="autofac" />    </files>  </autofacMvc>  <autofacWcf>    <files>      <!--<file name="configs/IocDAL.config" section="autofac" />-->    </files>  </autofacWcf>  <!--↑↑↑↑autofac配置结束↑↑↑↑-->

在上述webconfig中为了统一管理配置,具体指定接口、实现类、和注入实例的生命周期放到了configs/CoreService.config文件中

CoreService.config

<?xml version="1.0" encoding="utf-8"?><configuration>    <configSections>        <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/>    </configSections>    <autofac>        <components>      <!--DbContext上下文的生命周期为【per-lifetime-scope】即http请求的生命周期 -->      <component type="Autofac.DataModel.VehicleCheckDBEntities, Autofac.DataModel"                        service="System.Data.Entity.DbContext, EntityFramework"                       instance-scope="per-lifetime-scope"/>            <component type="Autofac.UnitOfWork.UnitOfWork, Autofac.UnitOfWork" service="Autofac.UnitOfWork.IUnitOfWork, Autofac.UnitOfWork" />                        <component type="Autofac.CoreService.Impl.UserManage, Autofac.CoreService" service="Autofac.CoreService.IUserManage, Autofac.CoreService" />            <component type="Autofac.CoreService.Impl.RoleManage, Autofac.CoreService" service="Autofac.CoreService.IRoleManage, Autofac.CoreService" />        </components>    </autofac></configuration>

说明:

1component组件配置中type、service配置的是实现类、程序集名称(不是命名空间)、接口、程序集名称。

2instance-scope 配置的是实例的生命周期。本例中用到两种:

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表