使用Microsoft.Practices.Unity 依赖注入

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 的基本用法介绍。

时间: 2024-08-04 04:02:58

使用Microsoft.Practices.Unity 依赖注入的相关文章

WebApi学习笔记06:使用webapi模板--仓储模式--Unity依赖注入

1.Web项目 1.1概述 对数据操作封装使用存储模式是很常见的方式,而使用依赖注入来降低耦合度(方便创建对象,可以抛弃经典的工厂模式)…… 1.2创建项目 1.3添加模型 在Models下,添加Product.cs: namespace WebApi06.Models { public class Product { public int ID { get; set; } public string Name { get; set; } public decimal Price { get;

验证Unity依赖注入的对象是否为同一个实例

在使用Unity的时候,能够很好的解耦,解除层与层之间的依赖性.这里有一个问题,每次向Unity中要对象实例的时候,这时候给出的是同一个吗?还是每次都是new一个新的?我来写代码验证一下.怎么验证两个对象是否为同一个呢,看这个对象在内存中的地址就行了,通过Hash码查看就可以. namespace UnityApplication { public interface IService { string Show(); } } namespace UnityApplication { publi

WPF PRISM开发入门二(Unity依赖注入容器使用)

这篇博客将通过一个控制台程序简单了解下PRISM下Unity依赖注入容器的使用.我已经创建了一个例子,通过一个控制台程序进行加减乘除运算,项目当中将输入输出等都用接口封装后,结构如下: 当前代码可以点击这里下载. 运行效果如下: 下面将引入Unity类库,使用Unity来生成需要的对象实例. 先查看一下CalculateRelpLoop类, public class CalculateRelpLoop : ICalculateRelpLoop { ICalculateService _calcu

Microsoft.Practices.Unity入门

Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入(Constructor Injection).属性注入(Property Injection),以及方法调用注入(Method Call Injection).现在Unity最新的版本的1.2版,可以在微软的开源站点http://unity.codeplex.com下载最新的发布版本和文档.通过使用Uni

Unity 依赖注入

关于Ioc的框架有很多,比如astle Windsor.Unity.Spring.NET.StructureMap,我们这边使用微软提供的Unity做示例,你可以使用Nuget添加Unity,也可以引用Microsoft.Practices.Unity.dll和Microsoft.Practices.Unity.Configuration.dll,下面我们就一步一步的学习下Unity依赖注入的详细使用.如果不明白什么是控制反转和依赖注入,请参考控制反转和依赖注入模式 下面通过一个示例来讲解Uni

Unity依赖注入

一.简介 Unity是一个轻量级的可扩展的依赖注入容器,支持构造函数,属性和方法调用注入.Unity可以处理那些从事基于组件的软件工程的开发人员所面对的问题.构建一个成功应用程序的关键是实现非常松散的耦合设计. 二.使用 1.安装 Unity插件. 进入NuGet,输入Unity.在相应的项目安装. 2.config中代码配置. 在configSections中加入    <section name="unity" type="Microsoft.Practices.U

Unity依赖注入使用详解

Unity依赖注入使用详解 写在前面 构造器注入 Dependency属性注入 InjectionMethod方法注入 非泛型注入 标识键 ContainerControlledLifetimeManager单例 Unity注册配置问题 Unity的app.config节点配置 后记 关于 控制反转 (Inversion of Control)和 依赖注入 (Dependency Injection)大家网上可以找下相关概念,在 <小菜学习设计模式(五)—控制反转(Ioc)> 这篇文章中本人也

第九回 Microsoft.Practices.Unity.Interception实现基于数据集的缓存(针对六,七,八讲的具体概念和配置的解说)

返回目录 概念 Microsoft.Practices.Unity.Interception是一个拦截器,它隶属于Microsoft.Practices.Unity组成之中,主要完成AOP的功能,而实现AOP方法拦截(页向切面)的基础就是IoC,我们需要配置相关接口或者类型的IoC方式,然后在生产对象时,使用Unity的方法进行动态生产对象,这时,你的Interception拦截器也会起作用! 相关技术 IoC: 控制反转(Inversion of Control,英文缩写为IoC)是一个重要的

.NET 用 Unity 依赖注入&mdash;&mdash;注册和解析类型

Unity Unity Application Block (Unity)是一个轻量级的,可扩展的依赖注入容器,它支持构造函数注入,属性注入和方法调用注入.它为开发人员提供了以下优点: 提供简化的对象创建,特别是层级对象结构和依赖,简化应用程序代码: 支持需求抽象:这可以让开发者在运行时或是配置文件指定依赖,简化横切关注点(crosscutting concerns)的管理: 通过延迟组件配置到容器,增加了灵活性: 具有服务定位器功能:这可以让客户存储或缓存容器.对 ASP.NET Web 应用