zoukankan      html  css  js  c++  java
  • Unity Container 应用示例

    一 项目引用Unity

    右键项目引用-> 管理Nuget包->搜索unity->安装Unity 和 Unity Interception Extension,如下图所示.

    Image

    二 创建基础类

    我们以商品查询的数据层注入为例.

    1.首先创建商品实体Model. 如果商品信息要被序列化,就要为该类添加Serializable特性.

    public class Product
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int Price { get; set; }
    
            public override string ToString()
            {
                return string.Format(" Product id:{0}
     Name:{1}
     Price:{2}
    ",Id,Name,Price);
            }
        }

    2.创建数据层接口及其实现类.

    public interface IProductDao
        {
            Product Get(int id);
        }
    public class ProductDao:IProductDao
        {
            public Product Get(int id)
            {
                #warning product info for test
                return new Product()
                {
                    Id = id,
                    Name = "Product"+id,
                    Price = id*10
                };
            }
        }

    3.直接创建实例

    其实有了以上内容就可以调用查询商品信息了.

    static void Main( string[] args) 
    
            { 
    
    IProductDao productDao= new ProductDao(); 
    
    Product product = productDao.Get(5); 
    
    Console.WriteLine(product.ToString()); 
    
    Console.Read(); 
    
            }

    Image

    不过在项目中使用这种方式的话,耦合度比较高.一旦想修改IProductDao的实现方式涉及到的地方就太多了. 使用Unity实现依赖注入可以降低耦合.

    三.使用Unity实现依赖注入

    1.创建Unity配置文件

    <? xml version= "1.0 "?> 
    < configuration> 
      < configSections> 
        <!-- unity程序集--> 
        < section name= "unity " type =" Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" /> 
      </ configSections> 
      < unity xmlns= "http://schemas.microsoft.com/practices/2010/unity "> 
        <!-- 程序集和命名空间 --> 
        < assembly name= "DemoCache "/> 
        < namespace name= "DemoCache.Dao "/> 
        < namespace name= "DemoCache.Dao.Impl "/> 
        < container name= "Dao "> 
          <!-- 商品 --> 
          < register type= "IProductDao " mapTo= "ProductDao "></ register> 
        </ container> 
      </ unity> 
    </ configuration>

    2.创建UnityContainerManager类

    创建UnityContainerManager读取Unity.config配置.  完整代码见附件,重点看一下从Unity.config读取配置信息的方法:

    private IUnityContainer LoadUnityConfig()
            {
                ////根据文件名获取指定config文件
                string filePath = AppDomain.CurrentDomain.BaseDirectory + @"ConfigsUnity.config";
                var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = filePath };
    
                //从config文件中读取配置信息
                Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
                var unitySection = (UnityConfigurationSection)configuration.GetSection("unity");
                var container = new UnityContainer();
                foreach (var item in unitySection.Containers)
                {
                    container.LoadConfiguration(unitySection, item.Name);
                }
    
                return container;
            }

    3.调用示例

    static void Main( string[] args) 
    
            { 
    
    IProductDao productDao = UnityContainerManager .Instance.Resolve<IProductDao >(); 
    Product product = productDao.Get(8); 
    Console.WriteLine(product.ToString()); 
    Console.Read(); 
    
            }
    Image

    四 使用Unity Interception实现日志

    1.创建ICallHandler接口实现类

    新建类LogCallHandler类,实现接口ICallHandler. 每次调用相应方法时会自动将执行时间写入日志.

    public class LogCallHandler:ICallHandler
        {
            public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
            {
                //计时开始
                var stopWatch = new Stopwatch();
                stopWatch.Start();
    
                //执行方法
                IMethodReturn result = getNext()(input, getNext);
    
                //计时结束
                stopWatch.Stop();
    
                //记录日志
    
                var argumentsSb = new StringBuilder(input.MethodBase.Name);
                for (var i = 0; i < input.Arguments.Count; i++)
                {
                    argumentsSb.AppendFormat("-{0}:{1}", input.Arguments.ParameterName(i), input.Arguments[i]);
                }
                LogHelper.LogInfo(string.Format("{2} 方法 {0},执行时间 {1} ms", argumentsSb, stopWatch.ElapsedMilliseconds,Msg));
                return result;
            }
    
            public int Order { get; set; }
            public string Msg { get; set; }
        }

    2.创建特性

    创建特性LogTime,它需要实现HandlerAttribute.

    public class LogTimeAttributes:HandlerAttribute
        {
            public int Order { get; set; }
            public string Msg { get; set; }
            public override ICallHandler CreateHandler(IUnityContainer container)
            {
                return new LogCallHandler()
                {
                    Order = Order,
                    Msg = Msg
                };
            }
        }

    3.使用特性

    [LogTimeAttributes (Order = 1,Msg = "查询单个商品信息" )]

    4.配置Unity.config

    配置Unity Interception需要在unity节点下添加:

    < sectionExtension 
    type =" Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension,Microsoft.Practices.Unity.Interception.Configuration ">
    </ sectionExtension >

    然后在container节点下添加:

    < extension type= "Interception " />

    最后调整IProductDao的注册节点:

    < register type= "IProductDao " mapTo= "ProductDao "> 
            < interceptor type =" InterfaceInterceptor" /> 
            < policyInjection /> 
    </ register>

    调用处不用做调整,结果如下:

    Image

    5.不使用Unity.config配置文件

    其实如果不走Unity.config配置文件,也可以直接在代码中设置.

    static void Main(string[] args)
            {        
                var container = new UnityContainer().AddNewExtension<Interception>().RegisterType<IProductDao, ProductDao>();
                container.Configure<Interception>().SetInterceptorFor<IProductDao>(new InterfaceInterceptor());
                IProductDao productDao = container.Resolve<IProductDao>();
                Product product = productDao.Get(8);
                Console.WriteLine(product);
                Console.Read();
            }

    代码: http://files.cnblogs.com/files/janes/DemoCache.zip

  • 相关阅读:
    Python数据可视化——散点图
    [ffmpeg 扩展第三方库编译系列] 关于 mingw32 下编译libcaca
    独立python环境之virtualenv和virtualenvwrapper
    深入理解maven及应用(一):生命周期和插件
    Android页面事件挂接模拟
    第六课 Struts的视图组件
    wxWidgets笔记_1_linux环境下wxwidgets的安装与配置
    使用 gradle 在编译时动态设置 Android resValue / BuildConfig / Manifes中&lt;meta-data&gt;变量的值
    ubuntu 下安装eclipse &amp;java环境配置
    [Swift]LeetCode695. 岛屿的最大面积 | Max Area of Island
  • 原文地址:https://www.cnblogs.com/janes/p/4620575.html
Copyright © 2011-2022 走看看