zoukankan      html  css  js  c++  java
  • 【Unity--Apwork框架】AOP编程--拦截,用于缓存和异常处理(Unity框架的拦截注入-Interception)

    第一步:定义拦截行为:CachingBehavior 和 ExceptionLoggingBehavior

               他们都继承接口:IInterceptionBehavior (程序集 Microsoft.Practices.Unity.Interception.dll, v2.1.505.0

                                                                      命名空间:Microsoft.Practices.Unity.InterceptionExtension)

               需要实现连个接口:

    public IEnumerable<Type> GetRequiredInterfaces()
    
    public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)

    CachingBehavior.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Keasy5.Infrastructure.Caching;
    using Microsoft.Practices.Unity.InterceptionExtension;
    
    namespace Keasy5.Infrastructure.InterceptionBehaviors
    {
        /// <summary>
        /// 表示用于方法缓存功能的拦截行为。
        /// </summary>
        public class CachingBehavior : IInterceptionBehavior
        {
            #region Private Methods
            /// <summary>
            /// 根据指定的<see cref="CachingAttribute"/>以及<see cref="IMethodInvocation"/>实例,
            /// 获取与某一特定参数值相关的键名。
            /// </summary>
            /// <param name="cachingAttribute"><see cref="CachingAttribute"/>实例。</param>
            /// <param name="input"><see cref="IMethodInvocation"/>实例。</param>
            /// <returns>与某一特定参数值相关的键名。
            ///   <remarks>
            ///    例如:<see cref="ICacheProvider.Add"/>
            ///   </remarks>
            /// </returns>
            private string GetValueKey(CachingAttribute cachingAttribute, IMethodInvocation input)
            {
                switch (cachingAttribute.Method)
                {
                    // 如果是Remove,则不存在特定值键名,所有的以该方法名称相关的缓存都需要清除
                    case CachingMethod.Remove:
                        return null;
                    // 如果是Get或者Put,则需要产生一个针对特定参数值的键名
                    case CachingMethod.Get:
                    case CachingMethod.Put:
                        if (input.Arguments != null &&
                            input.Arguments.Count > 0)
                        {
                            var sb = new StringBuilder();
                            for (int i = 0; i < input.Arguments.Count; i++)
                            {
                                sb.Append(input.Arguments[i].ToString());
                                if (i != input.Arguments.Count - 1)
                                    sb.Append("_");
                            }
                            return sb.ToString();
                        }
                        else
                            return "NULL";
                    default:
                        throw new InvalidOperationException("无效的缓存方式。");
                }
            }
            #endregion
    
            #region IInterceptionBehavior Members
            /// <summary>
            /// 获取当前行为需要拦截的对象类型接口。
            /// </summary>
            /// <returns>所有需要拦截的对象类型接口。</returns>
            public IEnumerable<Type> GetRequiredInterfaces()
            {
                return Type.EmptyTypes;
            }
    
            /// <summary>
            /// 通过实现此方法来拦截调用并执行所需的拦截行为。
            /// </summary>
            /// <param name="input">调用拦截目标时的输入信息。</param>
            /// <param name="getNext">通过行为链来获取下一个拦截行为的委托。</param>
            /// <returns>从拦截目标获得的返回信息。</returns>
            public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
            {
                var method = input.MethodBase;
                var key = method.Name;
                if (method.IsDefined(typeof(CachingAttribute), false))
                {
                    var cachingAttribute = (CachingAttribute)method.GetCustomAttributes(typeof(CachingAttribute), false)[0];
                    var valKey = GetValueKey(cachingAttribute, input);
                    switch (cachingAttribute.Method)
                    {
                        case CachingMethod.Get:
                            try
                            {
                                if (CacheManager.Instance.Exists(key, valKey))
                                {
                                    var obj = CacheManager.Instance.Get(key, valKey);
                                    var arguments = new object[input.Arguments.Count];
                                    input.Arguments.CopyTo(arguments, 0);
                                    return new VirtualMethodReturn(input, obj, arguments);
                                }
                                else
                                {
                                    var methodReturn = getNext().Invoke(input, getNext);
                                    CacheManager.Instance.Add(key, valKey, methodReturn.ReturnValue);
                                    return methodReturn;
                                }
                            }
                            catch (Exception ex)
                            {
                                return new VirtualMethodReturn(input, ex);
                            }
                        case CachingMethod.Put:
                            try
                            {
                                var methodReturn = getNext().Invoke(input, getNext);
                                if (CacheManager.Instance.Exists(key))
                                {
                                    if (cachingAttribute.Force)
                                    {
                                        CacheManager.Instance.Remove(key);
                                        CacheManager.Instance.Add(key, valKey, methodReturn.ReturnValue);
                                    }
                                    else
                                        CacheManager.Instance.Put(key, valKey, methodReturn.ReturnValue);
                                }
                                else
                                    CacheManager.Instance.Add(key, valKey, methodReturn.ReturnValue);
                                return methodReturn;
                            }
                            catch (Exception ex)
                            {
                                return new VirtualMethodReturn(input, ex);
                            }
                        case CachingMethod.Remove:
                            try
                            {
                                var removeKeys = cachingAttribute.CorrespondingMethodNames;
                                foreach (var removeKey in removeKeys)
                                {
                                    if (CacheManager.Instance.Exists(removeKey))
                                        CacheManager.Instance.Remove(removeKey);
                                }
                                var methodReturn = getNext().Invoke(input, getNext);
                                return methodReturn;
                            }
                            catch (Exception ex)
                            {
                                return new VirtualMethodReturn(input, ex);
                            }
                        default: break;
                    }
                }
    
                return getNext().Invoke(input, getNext);
            }
    
            /// <summary>
            /// 获取一个<see cref="Boolean"/>值,该值表示当前拦截行为被调用时,是否真的需要执行
            /// 某些操作。
            /// </summary>
            public bool WillExecute
            {
                get { return true; }
            }
    
            #endregion
        }
    }
    View Code

    ExceptionLoggingBehavior.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Practices.Unity.InterceptionExtension;
    
    namespace Keasy5.Infrastructure.InterceptionBehaviors
    {
        /// <summary>
        /// 表示用于异常日志记录的拦截行为。
        /// </summary>
        public class ExceptionLoggingBehavior : IInterceptionBehavior
        {
            #region IInterceptionBehavior Members
            /// <summary>
            /// 获取当前行为需要拦截的对象类型接口。
            /// </summary>
            /// <returns>所有需要拦截的对象类型接口。</returns>
            public IEnumerable<Type> GetRequiredInterfaces()
            {
                return Type.EmptyTypes;
            }
    
            /// <summary>
            /// 通过实现此方法来拦截调用并执行所需的拦截行为。
            /// </summary>
            /// <param name="input">调用拦截目标时的输入信息。</param>
            /// <param name="getNext">通过行为链来获取下一个拦截行为的委托。</param>
            /// <returns>从拦截目标获得的返回信息。</returns>
            public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
            {
                var methodReturn = getNext().Invoke(input, getNext);
                if (methodReturn.Exception != null)
                {
                    Utils.Log(methodReturn.Exception);
                }
                return methodReturn;
            }
            /// <summary>
            /// 获取一个<see cref="Boolean"/>值,该值表示当前拦截行为被调用时,是否真的需要执行
            /// 某些操作。
            /// </summary>
            public bool WillExecute
            {
                get { return true; }
            }
    
            #endregion
        }
    }
    View Code

    第二步:添加配置文件,为需要被拦截的类添加拦截行为。

    例如如下的配置,是为实现了接口

    Keasy5.ServiceContract.IProductService

    的类的所以方法添加拦截行为。

    web/app.config文件:

      <!--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" />
    。。。。。
    
          <register type="Keasy5.ServiceContract.IProductService, Keasy5.ServiceContract" mapTo="Keasy5.Application.Implementation.ProductServiceImpl, Keasy5.Application">
            <interceptor type="InterfaceInterceptor" />
            <interceptionBehavior type="Keasy5.Infrastructure.InterceptionBehaviors.CachingBehavior, Keasy5.Infrastructure" />
            <interceptionBehavior type="Keasy5.Infrastructure.InterceptionBehaviors.ExceptionLoggingBehavior, Keasy5.Infrastructure" />
          </register>
    
    。。。。

    比如:对于ExceptionLoggingBehavior的拦截行为作用于IProductService接口的实现类的所有方法:

            /// <summary>
            /// 通过实现此方法来拦截调用并执行所需的拦截行为。
            /// </summary>
            /// <param name="input">调用拦截目标时的输入信息。</param>
            /// <param name="getNext">通过行为链来获取下一个拦截行为的委托。</param>
            /// <returns>从拦截目标获得的返回信息。</returns>
            public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
            {
                var methodReturn = getNext().Invoke(input, getNext);
                if (methodReturn.Exception != null)
                {
                    Utils.Log(methodReturn.Exception);
                }
                return methodReturn;
            }

    效果是:如果IProductService接口的实现类的所有方法如果抛出了异常,将调用   

    Utils.Log(methodReturn.Exception);

    将异常信息写入日志系统(这就是我们进行拦截的目的)。

    
    

    ------------------------------------------------

    对应缓存CachingBehavior的拦截的补充:

    第一:定义特性:CachingAttribute

    CachingAttribute.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Keasy5.Infrastructure.Caching
    {
        /// <summary>
        /// 表示由此特性所描述的方法,能够获得来自基础结构层所提供的缓存功能。
        /// </summary>
        [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
        public class CachingAttribute : Attribute
        {
            #region Ctor
            /// <summary>
            /// 初始化一个新的<c>CachingAttribute</c>类型。
            /// </summary>
            /// <param name="method">缓存方式。</param>
            public CachingAttribute(CachingMethod method)
            {
                this.Method = method;
            }
            /// <summary>
            /// 初始化一个新的<c>CachingAttribute</c>类型。
            /// </summary>
            /// <param name="method">缓存方式。</param>
            /// <param name="correspondingMethodNames">
            /// 与当前缓存方式相关的方法名称。注:此参数仅在缓存方式为Remove时起作用。
            /// </param>
            public CachingAttribute(CachingMethod method, params string[] correspondingMethodNames)
                : this(method)
            {
                this.CorrespondingMethodNames = correspondingMethodNames;
            }
            #endregion
    
            #region Public Properties
            /// <summary>
            /// 获取或设置缓存方式。
            /// </summary>
            public CachingMethod Method { get; set; }
            /// <summary>
            /// 获取或设置一个<see cref="Boolean"/>值,该值表示当缓存方式为Put时,是否强制将值写入缓存中。
            /// </summary>
            public bool Force { get; set; }
            /// <summary>
            /// 获取或设置与当前缓存方式相关的方法名称。注:此参数仅在缓存方式为Remove时起作用。
            /// </summary>
            public string[] CorrespondingMethodNames { get; set; }
            #endregion
        }
    }
    View Code

    第二:将特性CachingAttribute应用于IProductService的接口方法:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.ServiceModel;
    using System.Text;
    using System.Threading.Tasks;
    using ByteartRetail.DataObjects;
    using Keasy5.DataObject;
    using Keasy5.Infrastructure;
    using Keasy5.Infrastructure.Caching;
    
    
    namespace Keasy5.ServiceContract
    {
        /// <summary>
        /// 表示与“商品”相关的应用层服务契约。
        /// </summary>
        [ServiceContract(Namespace = "http://www.ByteartRetail.com")]
        public interface IProductService : IApplicationServiceContract
        {
            #region Methods
            /// <summary>
            /// 创建商品信息。
            /// </summary>
            /// <param name="productDataObjects">需要创建的商品信息。</param>
            /// <returns>已创建的商品信息。</returns>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Remove, "GetProductsForCategory",
                "GetProductsWithPagination",
                "GetFeaturedProducts",
                "GetProductsForCategoryWithPagination",
                "GetProducts",
                "GetProductByID")]
            ProductDataObjectList CreateProducts(ProductDataObjectList productDataObjects);
            /// <summary>
            /// 创建商品分类。
            /// </summary>
            /// <param name="categoryDataObjects">需要创建的商品分类。</param>
            /// <returns>已创建的商品分类。</returns>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Remove, "GetCategories")]
            CategoryDataObjectList CreateCategories(CategoryDataObjectList categoryDataObjects);
            /// <summary>
            /// 更新商品信息。
            /// </summary>
            /// <param name="productDataObjects">需要更新的商品信息。</param>
            /// <returns>已更新的商品信息。</returns>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Remove, "GetProductsForCategory",
                "GetProductsWithPagination",
                "GetFeaturedProducts",
                "GetProductsForCategoryWithPagination",
                "GetProducts", "GetProductByID")]
            ProductDataObjectList UpdateProducts(ProductDataObjectList productDataObjects);
            /// <summary>
            /// 更新商品分类。
            /// </summary>
            /// <param name="categoryDataObjects">需要更新的商品分类。</param>
            /// <returns>已更新的商品分类。</returns>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Remove, "GetCategories", "GetCategoryByID")]
            CategoryDataObjectList UpdateCategories(CategoryDataObjectList categoryDataObjects);
            /// <summary>
            /// 删除商品信息。
            /// </summary>
            /// <param name="productIDs">需要删除的商品信息的ID值。</param>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Remove, "GetProductsForCategory",
                "GetProductsWithPagination",
                "GetFeaturedProducts",
                "GetProductsForCategoryWithPagination",
                "GetProducts", "GetProductByID")]
            void DeleteProducts(IDList productIDs);
            /// <summary>
            /// 删除商品分类。
            /// </summary>
            /// <param name="categoryIDs">需要删除的商品分类的ID值。</param>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Remove, "GetCategories", "GetCategoryByID")]
            void DeleteCategories(IDList categoryIDs);
            /// <summary>
            /// 设置商品分类。
            /// </summary>
            /// <param name="productID">需要进行分类的商品ID值。</param>
            /// <param name="categoryID">商品分类ID值。</param>
            /// <returns>带有商品分类信息的对象。</returns>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Remove, "GetProductsForCategory",
                "GetProductsForCategoryWithPagination")]
            CategorizationDataObject CategorizeProduct(Guid productID, Guid categoryID);
            /// <summary>
            /// 取消商品分类。
            /// </summary>
            /// <param name="productID">需要取消分类的商品ID值。</param>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Remove, "GetProductsForCategory",
                "GetProductsForCategoryWithPagination")]
            void UncategorizeProduct(Guid productID);
            /// <summary>
            /// 根据指定的ID值获取商品分类。
            /// </summary>
            /// <param name="id">商品分类ID值。</param>
            /// <param name="spec">查询方式。</param>
            /// <returns>商品分类。</returns>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Get)]
            CategoryDataObject GetCategoryByID(Guid id, QuerySpec spec);
            /// <summary>
            /// 获取所有的商品分类。
            /// </summary>
            /// <param name="spec">查询方式。</param>
            /// <returns>所有的商品分类。</returns>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Get)]
            CategoryDataObjectList GetCategories(QuerySpec spec);
            /// <summary>
            /// 根据指定的ID值获取商品信息。
            /// </summary>
            /// <param name="id">商品信息ID值。</param>
            /// <param name="spec">查询方式。</param>
            /// <returns>商品信息。</returns>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Get)]
            ProductDataObject GetProductByID(Guid id, QuerySpec spec);
            /// <summary>
            /// 获取所有的商品信息。
            /// </summary>
            /// <param name="spec">查询方式。</param>
            /// <returns>商品信息。</returns>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Get)]
            ProductDataObjectList GetProducts(QuerySpec spec);
            /// <summary>
            /// 以分页的方式获取所有商品信息。
            /// </summary>
            /// <param name="pagination">带有分页参数信息的对象。</param>
            /// <returns>经过分页的商品信息。</returns>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Get)]
            ProductDataObjectListWithPagination GetProductsWithPagination(Pagination pagination);
            /// <summary>
            /// 根据指定的商品分类ID值,获取该分类下所有的商品信息。
            /// </summary>
            /// <param name="categoryID">商品分类ID值。</param>
            /// <returns>所有的商品信息。</returns>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Get)]
            ProductDataObjectList GetProductsForCategory(Guid categoryID);
            /// <summary>
            /// 根据指定的商品分类ID值,以分页的方式获取该分类下所有的商品信息。
            /// </summary>
            /// <param name="categoryID">商品分类ID值。</param>
            /// <param name="pagination">带有分页参数信息的对象。</param>
            /// <returns>所有的商品信息。</returns>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Get)]
            ProductDataObjectListWithPagination GetProductsForCategoryWithPagination(Guid categoryID, Pagination pagination);
            /// <summary>
            /// 获取所有的特色商品信息。
            /// </summary>
            /// <param name="count">需要获取的特色商品信息的个数。</param>
            /// <returns>特色商品信息。</returns>
            [OperationContract]
            [FaultContract(typeof(FaultData))]
            [Caching(CachingMethod.Get)]
            ProductDataObjectList GetFeaturedProducts(int count);
            #endregion
        }
    }
    View Code

    第三:拦截IProductService接口的实现类的所有方法的所有方法,

    并通过CachingAttribute特性进行方法 的筛选,

    还进一步根据CachingAttribute的属性值进行一步的处理:

    CachingBehavior .cs

            /// <summary>
            /// 通过实现此方法来拦截调用并执行所需的拦截行为。
            /// </summary>
            /// <param name="input">调用拦截目标时的输入信息。</param>
            /// <param name="getNext">通过行为链来获取下一个拦截行为的委托。</param>
            /// <returns>从拦截目标获得的返回信息。</returns>
            public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
            {
                var method = input.MethodBase;
                var key = method.Name;
                if (method.IsDefined(typeof(CachingAttribute), false))
                {
                    var cachingAttribute = (CachingAttribute)method.GetCustomAttributes(typeof(CachingAttribute), false)[0];
                    var valKey = GetValueKey(cachingAttribute, input);
                    switch (cachingAttribute.Method)
                    {
                        case CachingMethod.Get:
                            try
                            {
                                if (CacheManager.Instance.Exists(key, valKey))
                                {
                                    var obj = CacheManager.Instance.Get(key, valKey);
                                    var arguments = new object[input.Arguments.Count];
                                    input.Arguments.CopyTo(arguments, 0);
                                    return new VirtualMethodReturn(input, obj, arguments);
                                }
                                else
                                {
                                    var methodReturn = getNext().Invoke(input, getNext);
                                    CacheManager.Instance.Add(key, valKey, methodReturn.ReturnValue);
                                    return methodReturn;
                                }
                            }
                            catch (Exception ex)
                            {
                                return new VirtualMethodReturn(input, ex);
                            }
                        case CachingMethod.Put:
                            try
                            {
                                var methodReturn = getNext().Invoke(input, getNext);
                                if (CacheManager.Instance.Exists(key))
                                {
                                    if (cachingAttribute.Force)
                                    {
                                        CacheManager.Instance.Remove(key);
                                        CacheManager.Instance.Add(key, valKey, methodReturn.ReturnValue);
                                    }
                                    else
                                        CacheManager.Instance.Put(key, valKey, methodReturn.ReturnValue);
                                }
                                else
                                    CacheManager.Instance.Add(key, valKey, methodReturn.ReturnValue);
                                return methodReturn;
                            }
                            catch (Exception ex)
                            {
                                return new VirtualMethodReturn(input, ex);
                            }
                        case CachingMethod.Remove:
                            try
                            {
                                var removeKeys = cachingAttribute.CorrespondingMethodNames;
                                foreach (var removeKey in removeKeys)
                                {
                                    if (CacheManager.Instance.Exists(removeKey))
                                        CacheManager.Instance.Remove(removeKey);
                                }
                                var methodReturn = getNext().Invoke(input, getNext);
                                return methodReturn;
                            }
                            catch (Exception ex)
                            {
                                return new VirtualMethodReturn(input, ex);
                            }
                        default: break;
                    }
                }
    
                return getNext().Invoke(input, getNext);
            }

    --------------------------------

    unity服务定位器:ServiceLocator

    ServiceLocator.cs 

    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.Configuration;
    
    
    namespace Keasy5.Infrastructure
    {
        /// <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>();
            }
    
            public IEnumerable<T> ResolveAll<T>()
            {
                return container.ResolveAll<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

     

  • 相关阅读:
    Java 集合类
    Java 中的四种引用及垃圾回收策略
    Java 类的加载过程(阿里面试题)
    JMeter进行一次简单的压力测试
    python使用 HTMLTestRunner.py生成测试报告
    python读取配置文件
    python的IDE工具-- Pycharm
    selenium webdriver+python基本操作
    SQL开发测试使用基础
    python学习笔记
  • 原文地址:https://www.cnblogs.com/easy5weikai/p/3790931.html
Copyright © 2011-2022 走看看