扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
1、配置文件
说明:此处有两个容器的节点,用来分别初始化两个容器,可以应对需要注入两个dbContext的情况。
代码:
2、初始化容器
说明:创建了一个枚举,用来对应配置文件中的两个节点,然后通过扩展方法获取到枚举值在配置文件中的节点名称,用来分别初始化不同的容器。
代码:
容器的工厂:
public class DIFactory
{
private static readonly object _SyncHelper = new object();
private static volatile Dictionary _UnityContainerDictionary = new Dictionary();
public static IUnityContainer GetContainer(EnContainer enContainer)
{
if (!_UnityContainerDictionary.ContainsKey(enContainer))
{
lock (_SyncHelper)
{
if (!_UnityContainerDictionary.ContainsKey(enContainer))
{
//配置UnityContainer
IUnityContainer container = new UnityContainer();
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
UnityConfigurationSection configSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
string strSection = enContainer.Speccn();
configSection.Configure(container, strSection);
_UnityContainerDictionary.Add(enContainer, container);
}
}
}
return _UnityContainerDictionary[enContainer];
}
}
枚举:
public enum EnContainer
{
[Speccn("yydyoaSection")]
YYDYOA = 1,
[Speccn("managerSection")]
MANAGER = 2
}
特性:
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
public class SpeccnAttribute : Attribute
{
private string Speccn { get; set; }
public SpeccnAttribute(string speccn)
{
this.Speccn = speccn;
}
public string GetSpeccn()
{
return this.Speccn;
}
}
扩展方法:
public static class EnumExtend
{
public static string Speccn(this Enum enContainer)
{
Type type = enContainer.GetType();
FieldInfo field = type.GetField(enContainer.ToString());
if (field.IsDefined(typeof(SpeccnAttribute), true))
{
SpeccnAttribute speccnAttribute = (SpeccnAttribute)field.GetCustomAttribute(typeof(SpeccnAttribute));
return speccnAttribute.GetSpeccn();
}
else
{
return enContainer.ToString();
}
}
}
3、接口和实现类的代码
接口:
public interface IDoWork
{
string Show(string arg);
}
实现类:
public class StudentDoWork : IDoWork
{
public string Show(string arg)
{
Console.WriteLine($"{this.GetType().Name}_DoWork Before");
Console.WriteLine($"{this.GetType().Name}_DoWork After");
return nameof(StudentDoWork);
}
}
public class TeacherDoWork : IDoWork
{
public string Show(string arg)
{
Console.WriteLine($"{this.GetType().Name}_DoWork");
return nameof(TeacherDoWork);
}
}
4、AOP扩展类的代码:
参数检查:
public class ParameterCheckBehavior : IInterceptionBehavior
{
public bool WillExecute => true;
public IEnumerable GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("ParameterCheckBehavior");
if (input.Inputs[0].ToString().Length < 10)//可以过滤一下敏感词
{
//返回一个异常
return input.CreateExceptionMethodReturn(new Exception("密码长度不能小于10位"));
}
else
{
Console.WriteLine("参数检测无误");
return getNext().Invoke(input, getNext);
}
}
}
日志:
public class LogBeforeBehavior : IInterceptionBehavior
{
public bool WillExecute => true;
public IEnumerable GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("LogBehavior before");
IMethodReturn method = getNext()(input, getNext);
Console.WriteLine("LogBehavior after");
return method;
}
}
异常:
public class ExpessionBehavior : IInterceptionBehavior
{
public bool WillExecute => true;
public IEnumerable GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("ExpessionBehavior before");
IMethodReturn method = getNext()(input, getNext);
if (method.Exception != null)
Console.WriteLine($"异常:{method.Exception.Message}");
Console.WriteLine("ExpessionBehavior after");
return method;
}
}
缓存:
public class CachingBehavior : IInterceptionBehavior
{
public IEnumerable GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
private static Dictionary CachingBehaviorDictionary = new Dictionary();
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
string key = $"{input.MethodBase.Name}_{Newtonsoft.Json.JsonConvert.SerializeObject(input.Inputs)}";
if (CachingBehaviorDictionary.ContainsKey(key))
{
return input.CreateMethodReturn(CachingBehaviorDictionary[key]);
}
else
{
IMethodReturn result = getNext().Invoke(input, getNext);
if (result.ReturnValue != null)
{
CachingBehaviorDictionary.Add(key, result.ReturnValue);
Console.WriteLine("CachingBehavior");
}
return result;
}
}
public bool WillExecute
{
get { return true; }
}
}
5、测试代码
static void Main(string[] args)
{
IUnityContainer yydyoaContainer = DIFactory.GetContainer(EnContainer.YYDYOA);
IDoWork doWork = yydyoaContainer.Resolve();
doWork.Show("12345678901234");
yydyoaContainer = DIFactory.GetContainer(EnContainer.MANAGER);
doWork = yydyoaContainer.Resolve();
doWork.Show("123");
Console.ReadKey();
}
6、总结
AOP扩展的进入顺序是根据配置文件从上到下进入,业务逻辑与拓展逻辑的执行顺序是根据getNext().Invoke(input, getNext)代码的位置决定。
创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流