zoukankan      html  css  js  c++  java
  • MVC 简单框架起步-分层(二)

           框架当然离不开分层,最开始写 Hello Word 第一个程序,很简单,完全不需要其他,直接Console.Write() 一下就好。后来需要实现一个小小的9*9乘法表,直接在一个方法在里面实现,可当我们实现一个业务的时候,可能要个100行左右的代码量,将此这个业务拆分成几个方法块,然后进行组合调用,这样做的目的也是解耦,为了以后需求变更时更好的拓展,分层也是这个目的,常见的一般时 数据访问层DLL,业务数据层BLL,模型层Model,UI层,有时候还会有一个帮助层,和接口层,这些层之间关系如下       

                                

     这种实现方式看起来很基础,感觉和 最开始 拆分方法很类似,用的时候 New 一下,不过是方法放在同一个类库下,而分层是在一个新的类库中,另外要把类库生成 dll 添加进来。综合来看依赖性依旧很强,所以需要进行调整,采用控制反转的方式来解除强依赖关系,这里采用AutoFac 的技术来实现,调整后的框架结构如下:

            

    如上,接入 AutoFac (IOC) 后,就不必进行大量的New 操作,需要那个方法,直接通过接口向容器拿就好。只需要将 BLL,DLL层的接口继承 IDependency接口,然后在全局文件Global中 进行注册。对于用惯了 New 方式的人来说,代码简直优美的不行,当然对于IOC 控制反转 的工具有很多,像 微软自带的 MEF,和其他的第三方工具 AutoFac ,Unity、Spring.NET、StructureMap 等等,这里主推AutoFac 实现简单,好理解,效率高,我之前有用过微软自带的 MEF,也就那样,直到尝试了AutoFac,果然主流的东西还是更香一些。

    关于AutoFac 如何使用,这里做一个简要的说明,网上很多文章,说的不明不白,浅藏辄止,举几个简单的例子,感觉很简单,实际在项目使用的时候疑惑的地方很多。

    1. 如何批量注册IBLL 和IDLL层

    2. 同一个接口被多个类继承并实现,调用的时候如何区分

    3. 网上大多是Web层 直接通过容器调用DLL层,那么当web调用BLL层,BLL去调用DLL层时,BLL如何关联DLL层

    这些问题对于熟悉容器的人来说可能不值一提,但对于小白来说,很是纠结,一度迷惑了我很久。试想带着很多疑问去学习,或者说是不理解。这就是一根坎,总有一些路要独自一个人走,能走多远,走多快全靠自己领悟,如果没有领路人真的是费劲。这里记录一下

    1. 实际项目中,不可能挨个接口去注册,不现实,这里只需要定义一个公共接口类,让IBLL层,IDLL层 均继承此接口,然后再全局文件Global.asax 中注册此公共接口即可

      

                #region AtuoFac 注册
    
                Assembly[] assemblies = Directory.GetFiles(AppDomain.CurrentDomain.RelativeSearchPath, "*.dll").Select(Assembly.LoadFrom).ToArray();
                //创建autofac管理注册类的容器实例
                var builder = new ContainerBuilder();
                //注册所有实现了 IDependency 接口的类型
                Type baseType = typeof(IDependency);
                builder.RegisterAssemblyTypes(assemblies)
                //.Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract || type.GetCustomAttribute(typeof(ServiceAttribute)) != null)
                .Where(t => baseType.IsAssignableFrom(t) || baseType.IsAssignableFrom(t) && !t.IsAbstract)
                .AsSelf().AsImplementedInterfaces()
                .PropertiesAutowired().InstancePerLifetimeScope();
    
                //使用Autofac提供的RegisterControllers扩展方法来对程序集中所有的Controller一次性的完成注册
                builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
                builder.RegisterFilterProvider();
                //生成具体的实例
                var container = builder.Build();
                //下面就是使用MVC的扩展 更改了MVC中的注入方式.
                DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    
    
                #endregion

    2. 当同一个接口被多个类继承并实现时,按照常规,用接口对象去调用时,默认是后一个被注册的实现类覆盖前一个实现类。如果想区分开,可以采用 Attribute 特性的方式给实现类分别加上不同的名称,写一个根据特性名找对应实现类的公共方法,调用此方法即可

    3. 对于Web 层直接调用 DLL 层来说,很简单,直接添加接口对象,然后再构造函数中,赋值接口对象即可。当通过BLL 层来实现此方式时,需要做一个转变,我们先在BaseLL 层的基类中定义BaseDLL 为null

        public class BaseBLL<T> : IBaseBLL<T> where T : class, new()
        {
            //定义BasaDLL为 null
            protected IBaseDLL<T> BaseDLL = null;
    
            public int Add(T model)
            {
                return BaseDLL.Add(model);
            }
        }

    然后在BLL业务实现类中的构造函数中对 该业务实现类对应的 数据访问类接口对象进行赋值,以及该业务实现类的基类进行赋值,具体赋值操作如下

        public class MenuBLL:BaseBLL<Menu>,IMenuBLL
        {
            IMenuDLL MenuDLL { set; get; }
            public MenuBLL(IMenuDLL dLL)
            {
                BaseDLL = dLL;
                MenuDLL = dLL;
            }
        }

    如此,需要调用函数时候,用同样的方式在控制器所在的构造函数中进行赋值,便可以通过容器任意调用BLL层中的函数

        public class HomeController : Controller
        {
            public IMenuBLL MenuBLL { set; get; }
            public HomeController(IStudentBLL bLL)
            {
                MenuBLL = menuBLL;
            }
    
           .....
    
         }
  • 相关阅读:
    Ternsorflow 学习:002-Tensorflow 基础知识
    Ternsorflow 学习:001-通过例程,初步了解Tensorflow
    Wpa_supplicant 调试故障原因分析
    Ternsorflow 学习:000-在 Ubuntu 16.04 上安装并使用 TensorFlow_v1.14 (改)
    开发工具类(eclipse、安卓SDK) 镜像站
    Linux镜像源 国内列表
    linux桌面系统 镜像下载
    arm linux 移植 udhcp 与 使用
    Docker三剑客之compose
    Docker基础内容之端口映射
  • 原文地址:https://www.cnblogs.com/Sientuo/p/13216489.html
Copyright © 2011-2022 走看看