第十六回 IoC组件Unity续~批量动态为Unity添加类型和行为

回到目录

之前的一篇Unity的文章主要是基本的实现,并没有什么特别的地方,使用Unity可以方便的实现应用程序的IoC控制反转,这给我们的应用程序在耦合度上变得高了,同时可测试性加强了,当然,这些的前提都是面向接口编程,如果你面向了具体实现去写程序,那你不用再看本篇文章了,呵呵。

本文章主要分享一下,通过Unity组件里的服务定位器ServiceLocator来实现批量加载类型,即你不用那它们一个个的配置到config文件里了,甚至在进行动态加载时,同时可以为它添加一些行为,如缓存,呵呵 !

下面说一下实现思想

首先unity有自己的容易UnityContainer,我们的配置信息都是向它里面添加的,它公开了RegisterType方法,用来向容器里注册类型和行为(aop),我们就是通过这个方法将应用程序的bin目录下的指定dll里的所有接口实现类进行提取,并添加到UnityContainer容器里,这样就实现了批量的动态的注册类型!

我的project.Ioc项目结构(来自仓储大叔框架集)

修改ServiceLocator文件的内容

添加了指定的私有方法来干这事

        /// <summary>
        /// 装载一批动态的类型
        /// Author:zhangzhanling
        /// Date:2015-04-03
        /// </summary>
        private void LoadDynamicType(IUnityContainer _container)
        {
            //unity动态类型注入,各个程序集用,分开,支持*通配符号
            string unityDynamicAssembly = System.Configuration.ConfigurationManager.AppSettings["unityDynamicAssembly"];
            //是否同时启动数据集缓存策略
            string unityCachingDoing = System.Configuration.ConfigurationManager.AppSettings["unityCachingDoing"];
            InjectionMember[] injectionMembers = null;
            if (unityCachingDoing == "1")
            {
                injectionMembers = new InjectionMember[] { new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<Project.UnityCaching.CachingBehavior>() };
            }
            if (!string.IsNullOrWhiteSpace(unityDynamicAssembly))
            {
                Array.ForEach(unityDynamicAssembly.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), dllName =>
                {
                    var baseDir = AppDomain.CurrentDomain.BaseDirectory;
                    if (System.Web.HttpContext.Current != null)
                    {
                        baseDir += "bin";
                    }
                    var files = Directory.GetFiles(baseDir, dllName);
                    var iTypes = new List<Type>();
                    foreach (var file in files)
                    {
                        var interfaceASM = Assembly.LoadFrom(Path.Combine(baseDir, file));
                        var types = from t in interfaceASM.GetTypes()
                                    where !string.IsNullOrWhiteSpace(t.Namespace)
                                    select t;

                        foreach (var type in types)
                        {
                            if (type.GetInterfaces() != null && type.GetInterfaces().Any())
                                foreach (var father in type.GetInterfaces())
                                {
                                    _container.RegisterType(father
                                        , type
                                        , injectionMembers);
                                }
                        }
                    }
                });

            }

        }

ServiceLocator中调用它

大功告成了,哈哈!

回到目录

posted @ 2015-04-03 17:43  张占岭  阅读(1799)  评论(1编辑  收藏  举报