• 使用Microsoft.Practices.Unity 依赖注入 转载https://www.cnblogs.com/slardar1978/p/4205394.html


    Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入(Constructor Injection)、属性注入(Property Injection),以及方法调用注入(Method Call Injection).

        假设我们有下面的场景代码,在代码里面有一个很简单的customer对象,customer 对象有个save 方法, 这个方法通过调用ICustomerDataAccess.Save将数据持久到数据库中, 在列子中我们实现了dataaccess的sql版本和mysql版本,也就是说我们这个customer对象,可以支持持久化到sql server 或 mysql.

           

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Practices.Unity;
    
    namespace UnitySample
    {
        public interface ICustomerDataAccess
        {
            void Save(Customer c);
        }
    
        public class CustomerSqlDataAccess : ICustomerDataAccess
        {
            public void Save(Customer c)
            {
                Console.Write("{2}, save data id:{0},name{1}",c.Id,c.Name,this.GetType().ToString());
            }
        }
    
        public class CustomerMysqlDataAccess : ICustomerDataAccess
        {
            public void Save(Customer c)
            {
                Console.Write("{2}, save data id:{0},name{1}", c.Id, c.Name, this.GetType().ToString());
            }
        }
    
        public class Customer
        {
            public ICustomerDataAccess CustomerDataAccess { get; set; }
    
            public string Id { get; set; }
            public string Name { get; set; }
    
            public void Save()
            {
                CustomerDataAccess.Save(this);
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
    
            }
        }
    }
    复制代码

    传统做法可能是在配置文件中填几个一个变量 dbType = sql  or my sql. 然后在customer 对象中根据设定的db type 来实力化不同的dataaccess.

       代码可能会是下面这个样子,这样的话,customer 对象实际上依赖于CustomerSqlDataAccess 和 CustomerSqlDataAccess 的,而且,未来比如要新增加其他数据库的支持,则必须修改customer 对象的源代码。

    复制代码
     public Customer()
     {
                if (DbType = "sql")
                {
                    CustomerDataAccess = new CustomerSqlDataAccess();
                }
                else
                {
                    CustomerDataAccess = new CustomerSqlDataAccess();
                }
     }
    复制代码

    下面我们使用unity 来解除customer 对象对  CustomerSqlDataAccess 和 CustomerSqlDataAccess 的依赖。

    一、 属性注入(Property Injection)

        1.  配置unity

         为了以后调用方便,我这里建立了一个静态方法,然后注入了两个dataaccess。

    复制代码
     public class UnitySetup
        {
            public static void Config()
            {
                var container = new UnityContainer();
                container.RegisterType<ICustomerDataAccess, CustomerSqlDataAccess>();
                container.RegisterType<ICustomerDataAccess, CustomerSqlDataAccess>("mysql");
            }
        }
    复制代码

      然后我们需要在Main函数中调用这个方法配置unity containter.

      

         static void Main(string[] args)
            {
                UnitySetup.Config();
            }

        2. 标记属性注入

       这步很简单,直接在customer 类中的ICustomerDataAccess 定义上面添加[Dependency]标注即可。

          

    [Dependency]
    public ICustomerDataAccess CustomerDataAccess { get; set; }

        3. 通过resove 获取对象

                var container = new UnityContainer();
                UnitySetup.Config(container);
                var sqlCustomer = container.Resolve<ICustomerDataAccess>();
                var mysqlCustomer = container.Resolve<ICustomerDataAccess>("mysql");

    上面的代码就分别获取了CustomerSqlDataAccess 实例和CustomerSqlDataAccess实例

    二 、构造器注入(Constructor Injection)

      1.  配置unity

        

      unityContainer.RegisterType<Customer>(
                    new InjectionConstructor(new ResolvedParameter<ICustomerDataAccess>()));
                unityContainer.RegisterType<Customer>("mysqlCustomer",
                    new InjectionConstructor(new ResolvedParameter<ICustomerDataAccess>("mysql")));

    添加两行注册customer 对想到container.

    2. 获取

     var sqlCustomer = container.Resolve<Customer>();
     var myqlCustomer = container.Resolve<Customer>("mysqlCustomer");

    完整代码如下
    复制代码
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Practices.Unity;
    
    namespace UnitySample
    {
        
        public interface ICustomerDataAccess
        {
            void Save(Customer c);
        }
    
        public class CustomerSqlDataAccess : ICustomerDataAccess
        {
            public void Save(Customer c)
            {
                Console.WriteLine("{2}, save data id:{0},name{1}",c.Id,c.Name,this.GetType().ToString());
            }
        }
    
        public class CustomerMysqlDataAccess : ICustomerDataAccess
        {
            public void Save(Customer c)
            {
                Console.WriteLine("{2}, save data id:{0},name{1}", c.Id, c.Name, this.GetType().ToString());
            }
        }
    
        public class UnitySetup
        {
            public static void Config(IUnityContainer unityContainer)
            {
                unityContainer.RegisterType<ICustomerDataAccess, CustomerSqlDataAccess>();
                unityContainer.RegisterType<ICustomerDataAccess, CustomerMysqlDataAccess>("mysql");
                unityContainer.RegisterType<Customer>(
                    new InjectionConstructor(new ResolvedParameter<ICustomerDataAccess>()));
                unityContainer.RegisterType<Customer>("mysqlCustomer",
                    new InjectionConstructor(new ResolvedParameter<ICustomerDataAccess>("mysql")));
            }
        }
    
        public class Customer
        {
            private ICustomerDataAccess CustomerDataAccess { get; set;}
    
            public string Id { get; set; }
            public string Name { get; set; }
    
            public Customer(ICustomerDataAccess customerDataAccess)
            {
                CustomerDataAccess = customerDataAccess;
            }
            public void Save()
            {
                CustomerDataAccess.Save(this);
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var container = new UnityContainer();
                UnitySetup.Config(container);
                var sqlCustomer = container.Resolve<Customer>();
                var myqlCustomer = container.Resolve<Customer>("mysqlCustomer");
    
                sqlCustomer.Save();
                myqlCustomer.Save();
                
                Console.ReadKey();
            }
        }
    }
    复制代码

    三 、 方法调用注入(Method Call Injection)

     方法调用注入和输入注入有点类似,只需要在调用的方法上面添加[InjectionMethod] 标注即可

      1.  配置unity

        

     unityContainer.RegisterType<Customer>("mysqlCustomer",
                    new InjectionMethod("SetDataAccess", new ResolvedParameter<ICustomerDataAccess>("mysql")));

    2. 获取

     var sqlCustomer = container.Resolve<Customer>();
     var myqlCustomer = container.Resolve<Customer>("mysqlCustomer");

     完成后的代码如下

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Practices.Unity;
    
    namespace UnitySample
    {
        
        public interface ICustomerDataAccess
        {
            void Save(Customer c);
        }
    
        public class CustomerSqlDataAccess : ICustomerDataAccess
        {
            public void Save(Customer c)
            {
                Console.WriteLine("{2}, save data id:{0},name{1}",c.Id,c.Name,this.GetType().ToString());
            }
        }
    
        public class CustomerMysqlDataAccess : ICustomerDataAccess
        {
            public void Save(Customer c)
            {
                Console.WriteLine("{2}, save data id:{0},name{1}", c.Id, c.Name, this.GetType().ToString());
            }
        }
    
        public class UnitySetup
        {
            public static void Config(IUnityContainer unityContainer)
            {
                unityContainer.RegisterType<ICustomerDataAccess, CustomerSqlDataAccess>();
                unityContainer.RegisterType<ICustomerDataAccess, CustomerMysqlDataAccess>("mysql");
                
                unityContainer.RegisterType<Customer>("mysqlCustomer",
                    new InjectionMethod("SetDataAccess", new ResolvedParameter<ICustomerDataAccess>("mysql")));
            }
        }
    
        public class Customer
        {
            private ICustomerDataAccess CustomerDataAccess { get; set;}
            public string Id { get; set; }
            public string Name { get; set; }
          
            public void Save()
            {
                CustomerDataAccess.Save(this);
            }
    
            [InjectionMethod]
            public void SetDataAccess(ICustomerDataAccess dataAccess)
            {
                CustomerDataAccess = dataAccess;
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var container = new UnityContainer();
                UnitySetup.Config(container);
                var sqlCustomer = container.Resolve<Customer>();
                var mysqlCustomer = container.Resolve<Customer>("mysqlCustomer");
                sqlCustomer.Save();
                mysqlCustomer.Save();
                Console.ReadKey();
            }
        }
    }
    复制代码

    好了,通过使用unity 依赖注入,customer 对象不再依赖具体的CustomerSqlDataAccess 和 CustomerMysqlDataAccess., 只依赖于接口ICustomerDataAccess。

    上面就是unity 的基本用法介绍。

  • 相关阅读:
    Aitit 认证体系之道 attilax著艾龙著 1. 认证体系分类 2 1.1. 按照语言来分 java net php 2 1.2. 按照平台来分 web cs 桌面 2 1.3. 综合性认证
    Atitit 数据库与存储引擎设计与实现 attilax总结 1.1. 数据库的实现有很多种, 遵循一些理论规范,如 Fix Rules、WriteAhead Log、Forcelogat
    Atitit 物联网之道 艾龙著 attilax著 1. 理论基础(控制理论 信息理论) 2 2. 1.5 物联网的关键技术12 2 2.1. 1.5.1 网络与通信技术12 1.5.2 无线传感
    Atitit 项目源码管理 attilax著 1. 源码结构sdk目录结构 1 1.1. 源码分类,配置文件,主程序文件,sql文件 1 2. 源码管理,提交,更新,与同步 1 2.1. 源码同步
    Atitit cio之道 attilax著 2. CIO是企业组织很重要的一个官员,未来就靠信息取胜了 1 3. Cio职责 2 3.1. 企业信息化 对信息技术的利用来实现组织攻略目标 2 3
    Aitit aop之道 艾龙著 需要整合zop资料包东西 第1章 AOP的产生         1.1 软件开发方法的演进         1.2 AOP产生的前奏——把系统看做一批关注点
    Atitit 运维之道 1.1.devops算是最低门槛了。什么运维平台,搞来搞去也就那些东西。无外乎cmdb、部署、监控之类的,再加点各种小平台自动化需求。 CMDB Configurati
    Atitit. Attilax软件研发and开发之道 1. 基本语言 3 2. 标准化库api 3 3. Ied与代码编写 调试 3 4. ui 3 5. 通讯 3 6. 第三方库 3 7. 数据
    Atitit sql之道 艾龙著 attilax 1. Ddl dml 3 2. Crud 3 3. 高级sql 3 3.1. Merge 3 3.2. 数据库翻页 limit offset系列
    Atitit 最近十年来until2018软件开发领域的趋势 艾龙总结 attilax大盘点总结历史与趋势 1. Keyword sec title 2 2. 语言本身: 2 2.1. 工业标准 2
  • 原文地址:https://www.cnblogs.com/Jeely/p/10967377.html
Copyright © 2020-2023  润新知