Unity 处理IOC AOP

Posted Zery

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity 处理IOC AOP相关的知识,希望对你有一定的参考价值。

用Unity 可以做IOC(控制反转) AOP(切面)可以做统一的异常和日志处理,非常方便,项目中是用微软企业库中的Microsoft.Practices.Unity实现


1 定义接口与实现

 

    //定义接口
    public interface IProductService
    {
        string GetProduct();
    }


    //实现接口
    public class ProductService:IProductService
    {
        public string GetProduct()
        {
            int i = 0;
            int j = 1;
            //抛异常
            return (j / i).ToString();
        }
    }

 

 2 实现依赖反转

 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

 

3 异常拦截类

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

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            var methodReturn = getNext().Invoke(input, getNext);
            if (methodReturn.Exception != null)
            {
                Console.WriteLine("拦截到异常 " + methodReturn.Exception.Message);
            }

            return methodReturn;
        }

        public bool WillExecute
        {
            get { return true; }
        }

    }

 

4 App.config 配置

<?xml version="1.0" encoding="utf-8" ?>
<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.2" />
    </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="UnityAOP.IProductService, UnityAOP" mapTo="UnityAOP.ProductService, UnityAOP">
        <interceptor type="InterfaceInterceptor"/>
        <!--<interceptionBehavior type="UnityAOP.CachingBehavior, UnityAOP"/>-->
        <interceptionBehavior type="UnityAOP.ExceptionLoggingBehavior, UnityAOP"/>
      </register>
    </container>
  </unity>
  <!--END: Unity-->
</configuration>

 

 

5 调用

static void Main(string[] args)
        {
            IProductService service =  ServiceLocator.Instance.GetService<IProductService>();
            try
            {
                service.GetProduct();
            }
            catch (Exception ex)
            {

            }

            Console.Read();
        }

 

 

简单的例子

代码:http://files.cnblogs.com/files/zery/UnityAOP.rar

如果在使用时提示如下错误:

创建 unity 的配置节处理程序时出错: The type name or alias Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration could not be resolved. Please check your configuration file and verify this type name. (d:\\我的文档\\visual studio 2015\\Projects\\KMML.Web\\KMML.Web\\web.config line 16)

 

请在Nuget中安装 Unity.Interceptio即可解决 

 

以上是关于Unity 处理IOC AOP的主要内容,如果未能解决你的问题,请参考以下文章

各种IoC框架下实现AOP

spring ioc aop 的原理

spring ioc和aop 啥设计模式

Spring中的ioc和aop有啥作用?为啥要用ioc和aop?面试中多次被问到,求一个详细 清晰的解答...

Spring框架-IOC和AOP

ioc、aop以及di