利用Unity实现AOP

.NET程序中,可以利用Unity来实现AOP,用来进行日志、缓存或权限的处理。这里我们来写一个简单的程序,让其实现简单的AOP功能。

1.使用NuGet,在项目中获取Microsoft.Practices.Unity。

2.新建一个ITalk类及其实现

    public interface ITalk
    {
        string Speak(string msg);
    }

    public class Talk : ITalk
    {
        public string Speak(string msg)
        {
            Console.WriteLine(msg);
            return msg;
        }
    }

3.再进一个ServiceLocator类,用来实现接口的依赖反转

using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;

namespace AopDemo
{
    /// <summary>
    /// Represents the Service Locator.
    /// </summary>
    public sealed class ServiceLocator : IServiceProvider
    {
        #region Private Fields
        private readonly IUnityContainer container;
        #endregion

        #region Private Static Fields
        private static readonly ServiceLocator instance = new ServiceLocator();
        #endregion

        #region Ctor
        /// <summary>
        /// Initializes a new instance of <c>ServiceLocator</c> class.
        /// </summary>
        private ServiceLocator()
        {
            UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            container = new UnityContainer();
            section.Configure(container);
        }
        #endregion

        #region Public Static Properties
        /// <summary>
        /// Gets the singleton instance of the <c>ServiceLocator</c> class.
        /// </summary>
        public static ServiceLocator Instance
        {
            get { return instance; }
        }
        #endregion

        #region Private Methods
        private IEnumerable<ParameterOverride> GetParameterOverrides(object overridedArguments)
        {
            List<ParameterOverride> overrides = new List<ParameterOverride>();
            Type argumentsType = overridedArguments.GetType();
            argumentsType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .ToList()
                .ForEach(property =>
                {
                    var propertyValue = property.GetValue(overridedArguments, null);
                    var propertyName = property.Name;
                    overrides.Add(new ParameterOverride(propertyName, propertyValue));
                });
            return overrides;
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Gets the service instance with the given type.
        /// </summary>
        /// <typeparam name="T">The type of the service.</typeparam>
        /// <returns>The service instance.</returns>
        public T GetService<T>()
        {
            return container.Resolve<T>();
        }
        /// <summary>
        /// Gets the service instance with the given type by using the overrided arguments.
        /// </summary>
        /// <typeparam name="T">The type of the service.</typeparam>
        /// <param name="overridedArguments">The overrided arguments.</param>
        /// <returns>The service instance.</returns>
        public T GetService<T>(object overridedArguments)
        {
            var overrides = GetParameterOverrides(overridedArguments);
            return container.Resolve<T>(overrides.ToArray());
        }
        /// <summary>
        /// Gets the service instance with the given type by using the overrided arguments.
        /// </summary>
        /// <param name="serviceType">The type of the service.</param>
        /// <param name="overridedArguments">The overrided arguments.</param>
        /// <returns>The service instance.</returns>
        public object GetService(Type serviceType, object overridedArguments)
        {
            var overrides = GetParameterOverrides(overridedArguments);
            return container.Resolve(serviceType, overrides.ToArray());
        }
        #endregion

        #region IServiceProvider Members
        /// <summary>
        /// Gets the service instance with the given type.
        /// </summary>
        /// <param name="serviceType">The type of the service.</param>
        /// <returns>The service instance.</returns>
        public object GetService(Type serviceType)
        {
            return container.Resolve(serviceType);
        }

        #endregion
    }
}

4.接下来是错误和缓存处理的类。我们这边只是简单的在控制台输出一句话,证明代码有执行。

ExceptionLoggingBehavior.cs

public class ExceptionLoggingBehavior : IInterceptionBehavior
    {
        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Console.WriteLine("ExceptionLoggingBehavior");
            return getNext().Invoke(input, getNext);
        }

        public bool WillExecute
        {
            get { return true; }
        }
    }

CachingBehavior.cs

  public class CachingBehavior : IInterceptionBehavior
    {
        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Console.WriteLine("CachingBehavior");
            return getNext().Invoke(input, getNext);
        }

        public bool WillExecute
        {
            get { return true; }
        }
    }

5.配置App.Config文件

<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <!--BEGIN: Unity-->
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>
    <container>
      <extension type="Interception"/>
      <!--Cache Provider-->
      <register type="AopDemo.ITalk, AopDemo" mapTo="AopDemo.Talk, AopDemo">
        <interceptor type="InterfaceInterceptor"/>
        <interceptionBehavior type="AopDemo.InterceptionBehaviors.CachingBehavior, AopDemo"/>
        <interceptionBehavior type="AopDemo.InterceptionBehaviors.ExceptionLoggingBehavior, AopDemo"/>
      </register>
    </container>
  </unity>
  <!--END: Unity-->
</configuration>

6.调用

    static void Main(string[] args)
        {
            ITalk talk = ServiceLocator.Instance.GetService<ITalk>();
            talk.Speak("Hello");
        }

7.结果

可以看到在打印出Hello前,代码先执行到了缓存与错误处理的方法。

时间: 2024-10-25 12:08:13

利用Unity实现AOP的相关文章

Java入门到精通——调错篇之Spring2.5利用aspect实现AOP时报错: error at ::0 can&#39;t find referenced pointcut XXX

一.问题描述及原因. 利用Aspect注解实现AOP的时候出现了error at ::0 can't find referenced pointcut XXX.一看我以为注解写错了,结果通过查询相关资料是因为Spring2.5与中的aspectjweaver.jar 和aspectjrt.jar这两个jar包与JDK1.7不匹配. org.springframework.beans.factory.BeanCreationException: Error creating bean with n

Entity Framework 实体框架的形成之旅--利用Unity对象依赖注入优化实体框架(2)

在本系列的第一篇随笔<Entity Framework 实体框架的形成之旅--基于泛型的仓储模式的实体框架(1)>中介绍了Entity Framework 实体框架的一些基础知识,以及构建了一个简单的基于泛型的仓储模式的框架,例子也呈现了一个实体框架应用的雏形,本篇继续介绍这个主题,继续深化介绍Entity Framework 实体框架的知识,以及持续优化这个仓储模式的实体框架,主要介绍业务逻辑层的构建,以及利用Unity和反射进行动态的对象注册. 1.EDMX文件位置的调整 我们从上篇例子,

【Unity】AOP编程--拦截,用于缓存和异常处理

第一步:定义拦截行为:CachingBehavior 和 ExceptionLoggingBehavior 他们都继承接口:IInterceptionBehavior (程序集 Microsoft.Practices.Unity.Interception.dll, v2.1.505.0 命名空间:Microsoft.Practices.Unity.InterceptionExtension) 需要实现连个接口: public IEnumerable<Type> GetRequiredInter

C# Unity依赖注入利用Attribute实现AOP功能

使用场景? 很多时候, 我们定义一个功能, 当我们要对这个功能进行扩展的时候, 按照常规的思路, 我们一般都是利用OOP的思想, 在原有的功能上进行扩展. 那么有没有一种东西, 可以实现当我们需要扩展这个功能的时候, 在不修改原来的功能代码的情况下实现, 这就是下面要说的到Unity. 1.准备工作 为项目添加NuGet包, 搜索Unity并且安装. 在使用的项目中添加Unity的相关引用 using Microsoft.Practices.Unity.InterceptionExtension

【转载】利用Unity自带的合图切割功能将合图切割成子图

虽然目前网上具有切割合图功能的工具不少,但大部分都是自动切割或者根据plist之类的合图文件切割的, 这种切割往往不可自己微调或者很难维调,导致效果不理想. 今天逛贴吧发现了一位网友写的切割合图插件很不错,就分享下, 利用的是Unity自带的合图切割功能,原生的切割功能虽然很方便而且很容易微调,但无法导出,这个网友将它们导出了, 来自:百度Unity3D贴吧的13471713164 链接:http://tieba.baidu.com/p/3217039693 using UnityEngine;

利用Unity自带的合图切割功能将合图切割成子图

转载的,牛人无处不在,我还太渺小 虽然目前网上具有切割合图功能的工具不少,但大部分都是自动切割或者根据plist之类的合图文件切割的, 这种切割往往不可自己微调或者很难维调,导致效果不理想. 今天逛贴吧发现了一位网友写的切割合图插件很不错,就分享下, 利用的是Unity自带的合图切割功能,原生的切割功能虽然很方便而且很容易微调,但无法导出,这个网友将它们导出了, 来自:百度Unity3D贴吧的13471713164 链接:http://tieba.baidu.com/p/3217039693 1

使用Unity进行AOP对象拦截

Unity 是一款知名的依赖注入容器( dependency injection container) ,其支持通过自定义扩展来扩充功能. 在Unity软件包内 默认包含了一个对象拦截(Interception)扩展定义. 本篇文章将介绍如何使用对象拦截(Interception)来分离横切关注点(Separation of cross-cutting concerns). 对象拦截简介 对象拦截(Interception)是一种 AOP(Aspect-oriented programming)

Unity实现AOP(用于实现缓存)

先下载这个NUGET包. 个人理解UINITY是在IOC上实现的AOP(自己试验了好多次),所以先定义接口跟实现类. namespace Cache { public class Talk : ITalk { [Caching(CachingMethod.Get)] public System.Collections.Generic.List<string> GetData() { Data.UpData(); return Data.GetData(); } } } namespace Ca

.NET中使用unity实现aop

Unity是一款知名的依赖注入容器,其支持通过自定义扩展来扩充功能.在Unity软件包内默认包含了一个对象拦截(Interception)扩展定义.本篇文章将介绍如何使用对象拦截功能来帮助你分离横切关注点(Separation of cross-cutting concerns). 对象拦截简介 对象拦截是一种AOP(Aspect-oriented programming)编程的实践方法.其可帮助你保持业务类的纯净,而无需考虑诸如日志和缓存等外围关注点. 在.NET中,实现AOP有多种方法.一种