• 我的开发框架(WinForm)3


    今天继续给大家介绍核心库的IOC的使用,在我的框架里,IOC使用的比较简单,主要是用于解除模块间的耦合和实例化接口。

    1、接口说明,IocContainer接口比较简单只有3个方法,但是是系统中用的最多的。

    IocContainer

    2、接口的实现。我用的是AutoFac,选用他基于2个方面的考虑,第一是对MEf和泛型的支持,第二是效率

    image

    园子里的Leepy 已经对比过主流的IOC框架,http://www.cnblogs.com/liping13599168/archive/2011/07/17/2108734.html

    时间比较早了,有兴趣的可以用最新的类库测试一下。

    AutoFac有对MEF的扩展插件,很方便。这样做的好处是,我可以只在核心模块中引用AutoFac ,业务模块中无需引用,用Mef标示即可,对于团队开发来说,他无需再了解AutoFac如何使用。

    不多说了,上代码

        ContainerBuilder builder;
            IContainer _container = null;
            public AutofacContainer(params ComposablePartCatalog[] catalogs)
            {
                builder = new ContainerBuilder();
    
                bool isRegisterOrm = false;
                foreach (var item in catalogs)
                {
                    builder.RegisterComposablePartCatalog(item);
                    
                    if (item is DirectoryCatalog && !isRegisterOrm)
                    {
                        DirectoryCatalog dir=item as DirectoryCatalog;
                    }
                }
               
            }
    
    

    其中ComposablePartCatalog 是MEF的东东,ContainerBuilder 是AutoFac的东西, 这一步主要是讲Mef的组件注册到AutoFac里。然后通过 IContainer Container=builder.Build(Autofac.Builder.ContainerBuildOptions.IgnoreStartableComponents); 这个方法初始化完成,我测试的时候发现这个方法,只能执行一次,第二次就报错。对应IocContainer.GetInstance 这个方法的实现就简单了,调用Autofac的对应的方法就行了bool bl = Container.TryResolve<T>(out t);返回t 就OK了,

     
     

    需要注意的是,Mef对泛型支持的不太好,所以需要单独处理。

    对于IRepository<T>和IRepository<T,Tid>接口来说,最理想的的情况是,我需要处理哪个实体类,就直接用var rep=  IocContainer.GetInstance<IRepository<T>>() 这种方式,就能到IRepository<T>的实例,然后进行后面的操作了。

    首先获得加载文件的所有 Assembly,然后判断他的名字是否以"Repository`1"结尾,然后调用AutoFac的泛型注册方法,注册,

    Assembly ass = Assembly.LoadFile(filepath);
    Type[] types = ass.GetTypes().Where(t => t.Name.EndsWith("Repository`1")).ToArray();
    if (types.Length > 0 && types[0].Name != "IRepository`1")
    {
    builder.RegisterGeneric(types[0]).As(typeof(IRepository<>));
    isload = true;
    }
    由于本人对Autofac 也是一知半解,只能用笨办法,肯定有好的办法,只是我还不知道.望园子里的高手指点一下。
    通过IocContainer接口,我们就可以创建并使用所有的接口了。
    3、使用
       在Core中我设计了一个全局静态类ApplicationEx,把IocContainer接口作为一个只读属性暴露出来,接口的实例化操作都在ApplicationEx的初始化中完成,在其他启动的时候,初始化ApplicationEx一次,保证IOC被初始化一次,后面所有模块的直接使用ApplicationEx的Container属性。这就达到了我们想要的目的。
    4、扩展
    我是一个比较懒的人,不想每次都写var rep=  IocContainer.GetInstance<IRepository<T>>() ,觉得写得有点多
    然后在Core里给IocContainer 增加了个扩展方法,
     /// <summary>
            /// 获得数据操作仓库接口
            /// </summary>
            /// <typeparam name="T">操作的实体类</typeparam>
            /// <returns>IRepository{``0}.</returns>
            public static IRepository<T> GetRepository<T>(this IocContainer ioc) where T : EntityBase, new()
            {
                return ioc.GetInstance<IRepository<T>>();
            }

    以后所有的模块调用就直接写var rep=  IocContainer.GetRepository<T>(),又少写了10几个字符,呵呵呵。

    今天就到这里吧,后面接着给大家介绍。

  • 相关阅读:
    从zk监控canal-client消费延迟情况
    python面向对象——类的参数
    python面向对象——类的继承
    python并发——进程间同步和通信(二)
    python并发——线程池与进程池(转)
    python从指定目录排除部分子目录——用于删除目录
    python并发统计s3目录大小
    Java对象的序列化和反序列化
    多态、抽象类和接口
    Java输入输出流
  • 原文地址:https://www.cnblogs.com/liuyh208/p/3286651.html
Copyright © 2020-2023  润新知