zoukankan      html  css  js  c++  java
  • 利用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
        }
    }
    View Code

    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; }
            }
        }
    View Code

    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; }
            }
        }
    View Code

    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前,代码先执行到了缓存与错误处理的方法。

    PS:如果IOC的时候报类似错误

    Exception is: InvalidOperationException - The type OAManageClient has multiple constructors of length 2. Unable to disambiguate.则配置文件应该增加<constructor></constructor>

     <register type="AopDemo.ITalk, AopDemo" mapTo="AopDemo.Talk, AopDemo">
            <interceptor type="InterfaceInterceptor"/>
            <interceptionBehavior type="AopDemo.InterceptionBehaviors.CachingBehavior, AopDemo"/>
            <interceptionBehavior type="AopDemo.InterceptionBehaviors.ExceptionLoggingBehavior, AopDemo"/>
            <constructor></constructor>
     </register>
    如果我的文章对你有帮助,就点一下推荐吧.(*^__^*)
  • 相关阅读:
    spring
    Hibernate中一级缓存和二级缓存使用详解
    myeclipse 配置weblogic
    小程序animation动画效果综合应用案例(交流QQ群:604788754)
    PHP:第二章——PHP中的equire与incude语句
    PHP:第二章——PHP中的break一continue一return语句
    PHP:第二章——PHP中的for语句
    PHP:第二章——PHP中的while语句
    PHP:第二章——PHP中的流程控制语句
    小程序animation动画效果(小程序组件案例)
  • 原文地址:https://www.cnblogs.com/Gyoung/p/3123022.html
Copyright © 2011-2022 走看看