标签:
.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前,代码先执行到了缓存与错误处理的方法。
标签:
原文地址:http://www.cnblogs.com/aaa6818162/p/4283206.html