当前位置:网站首页>iMedicalLIS listener (2)
iMedicalLIS listener (2)
2022-08-05 03:33:00 【Walk in loosing】
From listeners established programming to an interface,和MAfter calling method agreed.Then implement an interface is the first step to realize.This introduction to monitor implementation the infrastructure,检验网站、生成PDFProgram, has the structure.
spring.net为Java的spring框架在.net的实现.名为springEnterprise operation framework.Mainly provide featuresIOC、AOP、数据访问等.I mainly usespring.net的IOC和AOPAnd the attachmentspring的Log4Net写日志.详细可参照spring.net官方文档.我的spring.netExperience comes fromNSoft sail plan training,When Microsoft gold medal lecturer fighting all the teacher give us a lot of days lesson,很受用,在springI mainly use object-oriented inheritance before programming,It's not practical for polymorphic interface using,With the interface are directlynew对象的,Program to an interface is so fake.
The introduction of baidu:
Spring.NETIn order to establish enterprise applications to provide a set of lightweight solution.通过Spring.NET,我们可以用统一且透明的方式来配置应用程序.Spring.NET的重点是为中间层提供声明式事务管理,以及一个功能齐全的ASP.NET扩展框架.Spring.NET是非侵入式的,代码对框架本身不会产生任何依赖.
Spring.Core 库是框架的基础, 提供依赖注入功能.Spring NET中大多数类库依赖或扩展了Spring.Core的功能.IObjectFactory接口提供了一个简单而优雅的工厂模式,移除了对单例和一些服务定位stub的必要.允许你将真正的程序逻辑与配置解耦.作为对IObjectFactory 的扩展,IApplicationContext接口也在Spring.Core库中,
Spring DOTNET Is a focus on.NET企业应用开发的应用程序框架.It can provide a lot of aspects of the function,Such as inversion of control(Inversion of Control,英文缩写为IoC)、依赖注入(Dependency Injection,英文缩写DI)、面向方面编程(AOP)、数据访问抽象, 以及ASP DOTNET集成等.基于java的springFramework of the core concepts and value has been used to.NET.Spring DOTNET 1.0 Contains a fully functional dependency injection container andAOP库.The subsequent release will contain theASP DOTNET、RemotingAnd data access support.
我的介绍:
If you want to reach the programming to an interface,Requires that the caller does not see concrete implementation class.The caller is directed at the interface operations.而直接newObject is decided by way of not the real meaning of programming to an interface.Because use put really depend on the implementation class.为此需要IOC进行控制反转.IOCBy the container factory pattern design patterns.Used to put the incoming interface type returns the configuration implementation class.This decouplingnew依赖,Reach the programming to an interface.AOPThe dynamic proxy mode,AOP在IOCWhen the returned object withILLanguage to return to classes and the configuration of interceptor implementation class fusion is a dynamic and request class implements the same interface proxy class.So you can dynamically according to the configuration implementation aspect effect.如:Unified exception handling、统一的日志、The performance of the unified monitoring、统一的SQL日志.The unified function can be opened and closed according to the configuration at any time without intrusion code.这就是引入spring的强大之处.具体IOC和AOPImplementation can refer to my blogIOC和AOP实现.
This example shows that the following:
1.实现面向接口编程
2.使用spring.net
3.使用log4net
4.Why test listeners、网站、生成PDFThere is something wrong with the program always saidLogs,Good habit is watchingLogs.
5.检验webBackground through the container take business object in the same way,With the help of a container andAOPDecoupling and unification aspect,Just by name to find the implementation class or toConf配置找.
6.DotNet太lowImpression from dragging drag pulled the generally low threshold,Most people didn't introduce framework thought.
7.DotNetCore在spirng.net的延续
效果如下(Users don't need to care about the implementation class is who,Can be realized in the configuration change at any time.Get the cut surface of the object with at any time can be closed and open features):
1.First create a project introduction and packingspring.net和log4net
2.对容器进行包装
using System;
using System.Collections.Generic;
using Common.Logging;
using Spring.Context;
using Spring.Util;
using LIS.Core.BaseException;
using Spring.Context.Support;
using DemoDll.Util;
namespace DemoDll.Context
{
///<summary NoteObject="Class">
/// [功能描述: 框架容器,The container is the core of the entire framework,不可轻易改动]<br></br>
/// [创建者: 张联珠]<br></br>
/// [创建时间: 20220801]<br></br>
/// <说明>
///
/// </说明>
/// <修改记录>
/// <修改时间></修改时间>
/// <修改内容>
///
/// </修改内容>
/// </修改记录>
/// </summary>
public class ObjectContainer : IApplicationContextAware
{
#region 字段
/// <summary>
/// ObjectContainer实例
/// </summary>
private static readonly ObjectContainer instance = new ObjectContainer();
/// <summary>
/// IApplicationContext接口实例,Using the program context
/// </summary>
private IApplicationContext applicationContext;
#endregion
/// <summary>
/// Using the program context
/// </summary>
IApplicationContext IApplicationContextAware.ApplicationContext
{
set {
applicationContext = value; }
}
#region 构造
/ <summary>
/ 私有的构造函数,Prevention and control of privatisation created outside
/ </summary>
//private ObjectContainer()
//{
//}
#endregion
#region 共有方法
#region 非静态方法
/// <summary>
/// Whether the container containing the name of the specified object
/// </summary>
/// <param name="name">对象名称</param>
/// <returns>If the object container containing the name of the specified object,则为 true;否则为 false.</returns>
public bool InstanceContainsObject(string name)
{
// 验证applicationContext是否已经被初始化
CheackApplicationContext();
if (name == string.Empty)
{
LogUtils.WriteExceptionLog("传入参数为空:", new Exception("Query whether the container containing the name of the specified objectObjectContainer.InstanceContainsObject(name参数为空)."));
}
//检查参数是否为空
AssertUtils.ArgumentHasText(name, "name", "Query whether the container containing the name of the specified objectObjectContainer.InstanceContainsObject(name参数为空).");
//Return whether containing object
return applicationContext.ContainsObject(name);
}
/// <summary>
/// Whether object container containing specified object types
/// </summary>
/// <param name="type">对象类型</param>
/// <returns>If the object container containing the specified type,则为 true;否则为 false. </returns>
public bool InstanceContainsObject(Type type)
{
// 验证applicationContext是否已经被初始化
CheackApplicationContext();
if (type == null)
{
LogUtils.WriteExceptionLog("传入参数为空:", new Exception("Query whether the container containing the object of the specified typeObjectContainer.InstanceContainsObject(type参数为空)."));
}
//检查参数是否为空
AssertUtils.ArgumentNotNull(type, "type", "ObjectContainer.InstanceContainsObject(type参数为空).");
//Return whether containing object,用类型
return InstanceContainsObject(type.FullName);
}
/// <summary>
/// By name return objects
/// </summary>
/// <param name="name">对象名称</param>
/// <returns>返回对象</returns>
public object InstanceGetObject(string name)
{
// 验证applicationContext是否已经被初始化
CheackApplicationContext();
if (name == string.Empty)
{
LogUtils.WriteExceptionLog("传入参数为空:", new Exception("Returned to objects by nameObjectContainer.InstanceContainsObject(name参数为空)."));
}
//检查参数是否为空
AssertUtils.ArgumentHasText(name, "name", "ObjectContainer.InstanceContainsObject(name参数为空).");
//Back to objects by name
return applicationContext.GetObject(name);
}
/// <summary>
/// According to the type of the returned object
/// </summary>
/// <param name="type">对象类型</param>
/// <returns>返回对象</returns>
public object InstanceGetObject(Type type)
{
//Back to objects by type
return InstanceGetObject(type, false);
}
/// <summary>
/// According to the type of the returned object,If the object does not exist, based oncreateIfNotFoundDeciding whether to automatically according to the type to create objects
/// </summary>
/// <param name="type">对象类型</param>
/// <param name="createIfNotFound">If there is no object is automatically created</param>
/// <returns>返回的对象</returns>
public object InstanceGetObject(Type type, bool createIfNotFound)
{
// 验证applicationContext是否已经被初始化
CheackApplicationContext();
if (type == null)
{
LogUtils.WriteExceptionLog("传入参数为空:", new Exception("According to the type returned objectObjectContainer.InstanceContainsObject(type参数为空)."));
}
//检查参数是否为空
AssertUtils.ArgumentNotNull(type, "ObjectContainer.InstanceContainsObject(type参数为空).");
// 如果类型是接口
if (type.IsInterface)
{
//Get the type name
var names = applicationContext.GetObjectNamesForType(type);
//没获得
if (names.Length <= 0)
{
LisCoreException ex = new LisCoreException("NotFindDefinitions", String.Format("NotFindDefinitionsInfo", type.FullName));
LogUtils.WriteExceptionLog("Framework instance is created when the abnormal,Didn't get type full name:",ex);
throw ex;
}
//Get more,返回第一个
else if (names.Length == 1)
{
return InstanceGetObject(names[0]);
}
//获得一个,正常返回
else
{
return InstanceGetObject(names[0]);
}
}
else
{
//If you don't find and set to automatically create was not found
if (!InstanceContainsObject(type.FullName) && createIfNotFound)
{
return ObjectUtils.InstantiateType(type);
}
//返回对象
return InstanceGetObject(type.FullName);
}
}
/// <summary>
/// According to the type returned strongly typed objects
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <returns>返回的对象</returns>
public T InstanceGetObject<T>()
{
return InstanceGetObject<T>(false);
}
/// <summary>
/// According to the interface type returns a collection of objects
/// </summary>
/// <typeparam name="T">接口类型</typeparam>
/// <returns>对象集合</returns>
public IList<T> InstanceGetObjects<T>()
{
// 验证applicationContext是否已经被初始化
CheackApplicationContext();
//获取对象
var objects = applicationContext.GetObjectsOfType(typeof(T));
List<T> lstObject = new List<T>();
//填充集合
if (objects != null)
{
foreach (var obj in objects.Values)
{
lstObject.Add((T)obj);
}
}
//返回数据
return lstObject;
}
/// <summary>
/// According to the type returned strongly typed objects,If the object does not exist, based oncreateIfNotFoundDeciding whether to automatically according to the type to create objects
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="createIfNotFound">Can't find the object is automatically created when the</param>
/// <returns>返回的对象</returns>
public T InstanceGetObject<T>(bool createIfNotFound)
{
return (T)InstanceGetObject(typeof(T), createIfNotFound);
}
/// <summary>
/// By name return strongly typed objects
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="name">对象名称</param>
/// <returns>返回的对象</returns>
public T InstanceGetObject<T>(string name) where T : class
{
// 验证applicationContext是否已经被初始化
CheackApplicationContext();
if (name == string.Empty)
{
LogUtils.WriteExceptionLog("传入参数为空:", new Exception("Returned to strongly typed objects by nameObjectContainer.InstanceContainsObject(name参数为空)."));
}
//检查参数是否为空
AssertUtils.ArgumentHasText(name, "name", "ObjectContainer.InstanceContainsObject(name参数为空).");
//If the context contains no take object
if (!applicationContext.ContainsObject(name))
{
//创建对象
var t = (T)ObjectUtils.InstantiateType(typeof(T));
//创建失败的话,抛异常
if (t == null)
{
LisCoreException ex=new LisCoreException("CantCreateInstance",
string.Format(
"CantCreateInstanceInfo",
typeof(T).FullName));
LogUtils.WriteExceptionLog("By name to return to the strongly typed objects when an exception occurs,Cannot create the specified type of object:",ex);
throw ex;
}
return t;
}
Type type = applicationContext.GetType(name);
if (!(typeof(T).IsAssignableFrom(type)))
{
LisCoreException ex=new LisCoreException("TypeNotMatch", string.Format(
"TypeNotMatchInfo",
typeof(T).FullName, type.FullName));
LogUtils.WriteExceptionLog("By name to return to the strongly typed objects when an exception occurs,From the object cannot be converted to the target object:", ex);
throw ex;
}
return (T)InstanceGetObject(name);
}
/// <summary>
/// Returns the actual object type,Return type is introduced to type or subtype of incoming type
/// </summary>
/// <param name="type">类型</param>
/// <returns>实际的对象类型</returns>
public Type InstanceGetRealType(Type type)
{
// 验证applicationContext是否已经被初始化
CheackApplicationContext();
if (type == null)
{
LogUtils.WriteExceptionLog("传入参数为空:", new Exception("Returns the actual object typeObjectContainer.InstanceContainsObject(type参数为空)."));
}
//检查参数是否为空
AssertUtils.ArgumentNotNull(type, "ObjectContainer.InstanceContainsObject(type参数为空).");
//如果不包含,直接返回
if (!InstanceContainsObject(type))
{
return type;
}
//返回类型
return applicationContext.GetType(type.FullName);
}
/// <summary>
/// Does it include specified keyword message.
/// </summary>
/// <param name="key">消息关键字</param>
/// <returns>true:包含 false:不包含</returns>
public bool InstanceContainsMessage(string key)
{
try
{
this.applicationContext.GetMessage(key);
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Get the message from resource file.
/// </summary>
/// <param name="key">消息关键字</param>
/// <param name="msgParams">消息参数</param>
/// <returns>消息</returns>
public string InstanceGetMessage(string key, params string[] msgParams)
{
try
{
return this.applicationContext.GetMessage(key, msgParams);
}
catch
{
LisCoreException ex=new LisCoreException("NotFindResource", String.Format("NotFindResourceInfo", key));
LogUtils.WriteExceptionLog("From a resource file message when an exception occurs:",ex);
throw ex;
}
}
#endregion
#region 静态方法
/// <summary>
/// 返回唯一的ObjectContainer实例
/// </summary>
/// <returns>ObjectContainer实例</returns>
public static ObjectContainer GetInstance()
{
return instance;
}
/// <summary>
/// Whether object container containing specified object types
/// </summary>
/// <param name="type">对象类型</param>
/// <returns>If the object container containing the specified type,则为 true;否则为 false. </returns>
public static bool ContainsObject(Type type)
{
return GetInstance().InstanceContainsObject(type);
}
/// <summary>
/// Whether the container containing the name of the specified object
/// </summary>
/// <param name="name">对象名称</param>
/// <returns>If the object container containing the name of the specified object,则为 true;否则为 false.</returns>
public static bool ContainsObject(string name)
{
return GetInstance().InstanceContainsObject(name);
}
/// <summary>
/// According to the type returned strongly typed objects
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <returns>返回的对象</returns>
public static T GetObject<T>()
{
return GetInstance().InstanceGetObject<T>();
}
/// <summary>
/// According to the type returned strongly typed objects,Change method supports for objects to an attribute set value
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="propName">属性名称</param>
/// <param name="propValue">属性值</param>
/// <returns>返回的对象</returns>
public static T GetObject<T>(string propName,object propValue)
{
//获得类型
Type type=typeof(T);
//获取实体
T obj = GetInstance().InstanceGetObject<T>();
if (obj == null)
{
throw new Exception("spring 服务“" + type.FullName + "”The realization of the registration information is missing!");
}
Type proxyType = obj.GetType().GetInterface("LIS.DAL.DataAccess.IBaseService");
if (proxyType != null)
{
//获得属性信息
System.Reflection.PropertyInfo propertyInfo = proxyType.GetProperty(propName);
//设置属性值
if (propertyInfo != null && propValue != null && propertyInfo.PropertyType == propValue.GetType())
{
propertyInfo.SetValue(obj, propValue, null);
}
}
else
{
//获得属性信息
System.Reflection.PropertyInfo propertyInfo = type.GetProperty(propName);
//设置属性值
if (propertyInfo != null && propValue != null && propertyInfo.PropertyType == propValue.GetType())
{
propertyInfo.SetValue(obj, propValue, null);
}
}
return obj;
}
/// <summary>
/// According to the interface type returns a collection of objects
/// </summary>
/// <typeparam name="T">接口类型</typeparam>
/// <returns>对象集合</returns>
public static IList<T> GetObjects<T>()
{
return GetInstance().InstanceGetObjects<T>();
}
/// <summary>
/// According to the type returned strongly typed objects,If the object does not exist, based oncreateIfNotFoundDeciding whether to automatically according to the type to create objects
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="createIfNotFound">Whether to automatically create the object</param>
/// <returns>返回的对象</returns>
public static T GetObject<T>(bool createIfNotFound)
{
return GetInstance().InstanceGetObject<T>(createIfNotFound);
}
/// <summary>
/// By name return strongly typed objects
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="name">对象名称</param>
/// <returns>返回的对象</returns>
public static T GetObject<T>(string name) where T : class
{
return GetInstance().InstanceGetObject<T>(name);
}
/// <summary>
/// By name return objects
/// </summary>
/// <param name="name">对象名称</param>
/// <returns>返回对象</returns>
public static object GetObject(string name)
{
return GetInstance().InstanceGetObject(name);
}
/// <summary>
/// According to the type of the returned object
/// </summary>
/// <param name="type">对象类型</param>
/// <returns>返回对象</returns>
public static object GetObject(Type type)
{
return GetInstance().InstanceGetObject(type);
}
/// <summary>
/// According to the type of the returned object,If the object does not exist, based oncreateIfNotFoundDeciding whether to automatically according to the type to create objects
/// </summary>
/// <param name="type">对象类型</param>
/// <param name="createIfNotFound">Whether to automatically create the object</param>
/// <returns>返回的对象</returns>
public static object GetObject(Type type, bool createIfNotFound)
{
return GetInstance().InstanceGetObject(type, createIfNotFound);
}
/// <summary>
/// Returns the actual object type,Return type is introduced to type or subtype of incoming type
/// </summary>
/// <param name="type">类型</param>
/// <returns>实际的对象类型</returns>
public static Type GetObjectRealType(Type type)
{
return GetInstance().InstanceGetRealType(type);
}
/// <summary>
/// Get the message from resource file.
/// </summary>
/// <param name="key">消息关键字</param>
/// <param name="msgParams">消息参数</param>
/// <returns>消息</returns>
public static string GetMessage(string key, params string[] msgParams)
{
return GetInstance().InstanceGetMessage(key, msgParams);
}
/// <summary>
/// Does it include specified keyword message.
/// </summary>
/// <param name="key">消息关键字</param>
/// <returns>true:包含 false:不包含</returns>
public static bool ContainsMessage(string key)
{
return GetInstance().InstanceContainsMessage(key);
}
/// <summary>
/// Initialization and obtain applications context
/// </summary>
/// <returns></returns>
public static IApplicationContext GetContext()
{
return GetInstance().InnerGetContext();
}
/// <summary>
/// 刷新容器
/// </summary>
public static void RefreshContainer()
{
GetInstance().applicationContext=ContextRegistry.GetContext();
}
#endregion
#endregion
#region 私有方法
/// <summary>
/// Initialization and obtain the context
/// </summary>
/// <returns>Using the program context</returns>
private IApplicationContext InnerGetContext()
{
GetInstance().CheackApplicationContext();
return applicationContext;
}
/// <summary>
/// 验证applicationContext是否已经被初始化
/// </summary>
private void CheackApplicationContext()
{
if (applicationContext == null)
{
try
{
applicationContext = ContextRegistry.GetContext();
if (applicationContext == null)
{
var ex = new LisCoreException("NotInstantiatedContex", "NotInstantiatedContexInfo");
LogUtils.WriteExceptionLog("Initialization using the application context an exception occurs,请检查配置文件:", ex);
throw ex;
}
}
catch (Exception e)
{
if (applicationContext == null)
{
var ex = new LisCoreException("NotInstantiatedContex", "NotInstantiatedContexInfo"+e.InnerException.Message);
LogUtils.WriteExceptionLog("Initialization using the application context an exception occurs,请检查配置文件:", ex);
throw ex;
}
}
}
}
#endregion
}
}
3.The log for packaging
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.Logging;
using System.Text.RegularExpressions;
namespace DemoDll.Util
{
///<summary NoteObject="Class">
/// [功能描述: Logging tools]<br></br>
/// [创建者: 张联珠]<br></br>
/// [创建时间: 20220801]<br></br>
/// <说明>
///
/// </说明>
/// <修改记录>
/// <修改时间></修改时间>
/// <修改内容>
///
/// </修改内容>
/// </修改记录>
/// </summary>
public static class LogUtils
{
#region 静态成员
/// <summary>
/// Written exception log
/// </summary>
/// /// <param name="message">日志内容</param>
/// <param name="exception">异常对象</param>
public static void WriteExceptionLog(string message, Exception exception)
{
LogManager.GetLogger("Exception").Error(message, exception);
}
/// <summary>
/// Writing performance log
/// </summary>
/// <param name="message">日志内容</param>
public static void WriteCapabilityLog(string message)
{
LogManager.GetLogger("Capability").Info(message);
}
/// <summary>
/// Written security logs
/// </summary>
/// <param name="message">日志内容</param>
public static void WriteSecurityLog(string message)
{
LogManager.GetLogger("Security").Info(message);
}
/// <summary>
/// Write operation log
/// </summary>
/// <param name="message">日志内容</param>
public static void WriteOperationLog(string message)
{
LogManager.GetLogger("Operation").Info(message);
}
/// <summary>
/// Writing log
/// </summary>
/// <param name="message">日志内容</param>
public static void WriteDebugLog(string message)
{
LogManager.GetLogger("Debug").Debug(message);
}
/// <summary>
/// Writing log
/// </summary>
/// <param name="message">日志内容</param>
public static void WriteSqlLog(string message)
{
LogManager.GetLogger("SqlLog").Debug(ReplaceSpaceToOne(message));
}
/// <summary>
/// Multiple Spaces replace a
/// </summary>
/// <param name="str">To deal with the string of</param>
/// <returns>结果</returns>
private static string ReplaceSpaceToOne(string str)
{
string resultString = string.Empty;
try
{
resultString = Regex.Replace(str, "\\s{2,}", " ");
return resultString;
}
catch
{
return str;
}
}
#endregion
}
}
4.Using plane function interceptor
异常拦截器
using System;
using AopAlliance.Intercept;
using LIS.Core.BaseException;
using DemoDll.Util;
namespace DemoDll.Aop
{
///<summary NoteObject="Class">
/// [功能描述: Business exceptions interceptor,On the one hand, writing log,On the other hand the whole business layerfacadeNot to throw the ground floor to abnormal,Even throw the other abnormal,Also converted to a business exception]<br></br>
/// [创建者: 张联珠]<br></br>
/// [创建时间: 20220801]<br></br>
/// <说明>
///
/// </说明>
/// <修改记录>
/// <修改时间></修改时间>
/// <修改内容>
///
/// </修改内容>
/// </修改记录>
/// </summary>
public class BusinessExceptionAdvice : IMethodInterceptor
{
/// <summary>
/// Business exceptions to intercept calls the method
/// </summary>
/// <param name="invocation">方法信息</param>
/// <returns>返回值</returns>
public object Invoke(IMethodInvocation invocation)
{
try
{
return invocation.Proceed();
}
//捕获业务异常
catch (BusinessException ex)
{
//写日志
LogUtils.WriteExceptionLog(ex.Message, ex);
//抛出异常
throw ex;
}
//捕获数据库异常
catch (DataAccessException ex)
{
//写日志
LogUtils.WriteExceptionLog(ex.Message, ex);
//抛出异常
throw ex;
}
//Catch exceptions framework
catch (LisCoreException ex)
{
//写日志
LogUtils.WriteExceptionLog(ex.Message, ex);
//抛出异常
throw ex;
}
//If not this class,The exception into a business exception,Do not make direct regular exception thrown,因为WCFDeployment will cause abnormal channel
catch (Exception ex)
{
//写日志
LogUtils.WriteExceptionLog(ex.Message, ex);
BusinessException be = new BusinessException("Undefined business exception,Not by the business logic initiative to throw,By the framework into a business exception",ex.Message);
//抛出异常
throw be;
}
}
}
}
性能拦截器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using AopAlliance.Intercept;
using DemoDll.Util;
namespace DemoDll.Aop
{
///<summary NoteObject="Class">
/// [功能描述: 性能拦截器,On the day of the performance writing work]<br></br>
/// [创建者: 张联珠]<br></br>
/// [创建时间: 20220801]<br></br>
/// <说明>
///
/// </说明>
/// <修改记录>
/// <修改时间></修改时间>
/// <修改内容>
///
/// </修改内容>
/// </修改记录>
/// </summary>
public class CapabilityAdvice : IMethodInterceptor
{
/// <summary>
/// Business exceptions to intercept calls the method
/// </summary>
/// <param name="invocation"></param>
/// <returns></returns>
public object Invoke(IMethodInvocation invocation)
{
Stopwatch watch = new Stopwatch();
watch.Start();
var result = invocation.Proceed();
//Write performance log
LogUtils.WriteCapabilityLog("执行类" + invocation.TargetType.Name + "的方法" + invocation.Method.Name +"耗时:" + watch.Elapsed.TotalSeconds.ToString());
return result;
}
}
}
Operation log interceptor
using AopAlliance.Intercept;
using DemoDll.Util;
using System.Text;
namespace DemoDll.Aop
{
///<summary NoteObject="Class">
/// [功能描述: Operation log interceptor,Eligible for container object methods are writing method of input and output log]<br></br>
/// [创建者: 张联珠]<br></br>
/// [创建时间: 20220801]<br></br>
/// <说明>
///
/// </说明>
/// <修改记录>
/// <修改时间></修改时间>
/// <修改内容>
///
/// </修改内容>
/// </修改记录>
/// </summary>
public class OperationLogAdvice : IMethodInterceptor
{
/// <summary>
/// 拦截方法
/// </summary>
/// <param name="invocation">方法实例</param>
/// <returns>方法返回值</returns>
public object Invoke(IMethodInvocation invocation)
{
//输出类名,方法名
string methodString = string.Format("类名:{0}方法名:{1}", invocation.TargetType.Name, invocation.Method.Name);
StringBuilder sb = new StringBuilder();
sb.Append(methodString);
LogUtils.WriteOperationLog(methodString);
//有参数
if (invocation.Arguments != null && invocation.Arguments.Length > 0)
{
foreach (var arg in invocation.Arguments)
{
if (arg != null)
{
sb.Append("参数:" + arg.ToString());
}
else
{
sb.Append("参数:null");
}
}
LogUtils.WriteOperationLog(sb.ToString());
}
//执行方法
var result = invocation.Proceed();
//有结果的话,Write the results to the log
if (result != null)
{
sb.Append("结果:" + result.ToString());
}
LogUtils.WriteOperationLog(sb.ToString());
return result;
}
}
}
SQL日志拦截器
using System;
using AopAlliance.Intercept;
using DemoDll.Util;
using System.ComponentModel;
namespace DemoDll.Aop
{
///<summary NoteObject="Class">
/// [功能描述: SQL日志的拦截器,Through the data access layer to performsql都写入sql日志,方便查看]<br></br>
/// [创建者: 张联珠]<br></br>
/// [创建时间: 20220801]<br></br>
/// <说明>
///
/// </说明>
/// <修改记录>
/// <修改时间></修改时间>
/// <修改内容>
///
/// </修改内容>
/// </修改记录>
/// </summary>
public class SqlLogAdvice : IMethodInterceptor
{
/// <summary>
/// 是否要输出SQL关键字
/// </summary>
[DefaultValue(true)]
public bool OutputKey {
get; set; }
/// <summary>
/// 是否要输出SQL
/// </summary>
[DefaultValue(true)]
public bool OutputSql {
get; set; }
/// <summary>
/// 拦截方法
/// </summary>
/// <param name="invocation">方法实例</param>
/// <returns>方法返回值</returns>
public object Invoke(IMethodInvocation invocation)
{
string key = invocation.Arguments[0].ToString();
var result = invocation.Proceed();
if (this.OutputKey)
{
LogUtils.WriteOperationLog("SQL关键字: " + key);
}
if (this.OutputSql)
{
LogUtils.WriteOperationLog("SQL语句: " + result.ToString());
}
return result;
}
}
}
5.Then build a test project,引入spring的配置
<?xml version="1.0"?>
<configuration>
<!--spring配置-->
<configSections>
<sectionGroup name="spring">
<!---The three must be configured-->
<!--参数段-->
<section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core"/>
<!--Using the program context section-->
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<!--Total node configuration section-->
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
<!---->
</sectionGroup>
<sectionGroup name="common">
<!--日志段-->
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/>
</sectionGroup>
<!--日志段-->
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<common>
<logging>
<!--日志适配器-->
<factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net">
<arg key="configType" value="FILE-WATCH"/>
<arg key="configFile" value="~/Conf/Log4Net.xml"/>
</factoryAdapter>
</logging>
</common>
<spring>
<!--Introducing multiple file configuration,According to the feature classification object configuration with-->
<context>
<!--引入当前config的object节点-->
<resource uri="config://spring/objects"/>
<!--The introduction of relative pathConf下配置-->
<resource uri="~/Conf/AopConfig.xml"/>
<resource uri="~/Conf/ObjConfig.xml"/>
</context>
<objects>
<!--配置接口的实现类-->
<object id="Student" type="DemoDll.Test.Student,DemoDll" singleton="false">
</object>
</objects>
<parsers>
<parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data"/>
<parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data"/>
<parser type="Spring.Aop.Config.AopNamespaceParser, Spring.Aop"/>
</parsers>
</spring>
<appSettings>
<add key="WebServiceAddress" value=""/>
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
</configuration>
配置AOP,I realize the test class isStudentSo the configuration targets with.*dent.告诉springThe match object to add section.
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net" xmlns:aop="http://www.springframework.net/aop">
<!--必须让Spring.NET容器管理DefaultAdvisorAutoProxyCreator类-->
<object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop"/>
<!-- Operation log -->
<object id="OperationLogAdvice" type="DemoDll.Aop.OperationLogAdvice, DemoDll" />
<!-- Intercept operation log -->
<object type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">
<property name="advice" ref="OperationLogAdvice"/>
<property name="patterns">
<list>
<value>.*Service</value>
<value>.*Facade</value>
<value>.*Dal</value>
<value>.*Table</value>
<value>.*dent</value>
</list>
</property>
</object>
<!-- Exception handling logging interceptor -->
<object id="BllExceptionAdvice" type="DemoDll.Aop.BusinessExceptionAdvice, DemoDll" />
<!-- Exception handling logging interceptor -->
<object type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">
<property name="advice" ref="BllExceptionAdvice"/>
<property name="patterns">
<list>
<value>.*Service</value>
<value>.*Facade</value>
<value>.*Dal</value>
<value>.*Table</value>
<value>.*dent</value>
</list>
</property>
</object>
<!-- Performance logs to intercept -->
<object id="CapabilityAdvice" type="DemoDll.Aop.CapabilityAdvice, DemoDll" />
<!-- Performance logs to intercept -->
<object type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">
<property name="advice" ref="CapabilityAdvice"/>
<property name="patterns">
<list>
<value>.*Service</value>
<value>.*Facade</value>
<value>.*Dal</value>
<value>.*Table</value>
<value>.*dent</value>
</list>
</property>
</object>
</objects>
配置log4net
<?xml version="1.0" encoding="utf-8" ?>
<log4net debug="false">
<appender name="ExceptionRollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="LockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
<param name="DatePattern" value="yyyy-MM-dd.'log'" />
<file value="Logs/异常日志.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1024KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %15logger %appdomain %location -- %message %exception %newline" />
</layout>
</appender>
<appender name="DebugRollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="LockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
<param name="DatePattern" value="yyyy-MM-dd.'log'" />
<file value="Logs/调试日志.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1024KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date -- %message %exception %newline" />
</layout>
</appender>
<appender name="OperationRollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="LockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
<param name="DatePattern" value="yyyy-MM-dd.'log'" />
<file value="Logs/方法日志.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1024KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<appender name="SqlRollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="LockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
<param name="DatePattern" value="yyyy-MM-dd.'log'" />
<file value="Logs/Sql语句日志.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1024KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<appender name="CapabilityRollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="LockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
<param name="DatePattern" value="yyyy-MM-dd.'log'" />
<file value="Logs/性能.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1024KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<appender name="SecurityRollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="LockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
<param name="DatePattern" value="yyyy-MM-dd.'log'" />
<file value="Logs/安全.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1024KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
<root>
<level value="DEBUG"/>
</root>
<logger name="Exception">
<appender-ref ref="ExceptionRollingLogFileAppender" />
</logger>
<logger name="Operation">
<appender-ref ref="OperationRollingLogFileAppender"/>
</logger>
<logger name="Debug">
<appender-ref ref="DebugRollingLogFileAppender" />
</logger>
<logger name="SqlLog">
<appender-ref ref="SqlRollingLogFileAppender" />
</logger>
<logger name="Capability">
<appender-ref ref="CapabilityRollingLogFileAppender"/>
</logger>
<logger name="Security">
<appender-ref ref="SecurityRollingLogFileAppender"/>
</logger>
</log4net>
6.测试代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace SpringLog4Net
{
public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
}
/// <summary>
/// 加载
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FrmMain_Load(object sender, EventArgs e)
{
DemoDll.Test.IStudent stu = DemoDll.Context.ObjectContainer.GetObject<DemoDll.Test.IStudent>();
stu.Say("我是zhanglianzhu!");
DemoDll.Util.LogUtils.WriteDebugLog("通过Log4Net写日志,Logging can be configured to open or close");
}
}
}
7.运行之后,Get the object,Normal functions show the plane,在LogsThe folder under the log output
在DotNetCoreAfter already shipped container,所以spring.net没落了,那么在dotnetcoreAs to inheritspring.netCode assets to do.
Can you readspring.net格式配置xml反射实现容器
/// <summary>
/// 构造器
/// </summary>
private static ContainerBuilder builder = new ContainerBuilder();
/// <summary>
/// 初始化IOC容器
/// </summary>
public static void InitIoc()
{
//读取IOC路径下的XMLThe configuration file to reflect structureIOC
string IocPath = Path.Combine(AppContext.BaseDirectory, LIS.Core.MultiPlatform.LISConfigurtaion.Configuration["IocConfPath"]);
if (Directory.Exists(IocPath))
{
DirectoryInfo asmxdi = new DirectoryInfo(IocPath);
FileInfo[] asmxFiles = asmxdi.GetFiles();
if (asmxFiles != null && asmxFiles.Length > 0)
{
foreach (FileInfo fi in asmxFiles)
{
if (fi.Extension.ToLower() == ".xml")
{
string confStr = ReadTxt(fi.FullName);
//创建一个xml文档
XmlDocument xmlDoc = new XmlDocument();
//为文档导入数据
xmlDoc.LoadXml(confStr);
//获得根节点
XmlNode root = xmlDoc.LastChild;
//Get a return value node
XmlNodeList objConfs = root.ChildNodes;
if(objConfs!=null&& objConfs.Count>0)
{
foreach(XmlNode node in objConfs)
{
if(node.Name!= "object")
{
continue;
}
string typeStr= node.Attributes["type"].Value;
string idStr = "";
if (node.Attributes["id"]!=null)
{
idStr = node.Attributes["id"].Value;
}
string[] typeArr = typeStr.Split(',');
string singletonStr = node.Attributes["singleton"].Value;
Type serviceType = GetType(typeArr[0], typeArr[1]);
Type [] interArr=serviceType.GetInterfaces();
if(interArr!=null&& interArr.Length>0)
{
if(idStr!=null&&idStr!="")
{
if(!dicIdTypes.ContainsKey(idStr))
{
dicIdTypes.Add(idStr, interArr[0]);
}
else
{
throw new Exception("已包含id为:"+idStr+"The container configuration!");
}
}
foreach(Type it in interArr)
{
if(!dicTypes.ContainsKey(it))
{
dicTypes.Add(it, serviceType);
}
}
}
}
}
}
}
}
}
}
/// <summary>
/// 注册
/// </summary>
/// <typeparam name="TInterface">接口</typeparam>
/// <typeparam name="TImplementation">实现类</typeparam>
public static void Register<TInterface, TImplementation>() where TImplementation : TInterface
{
if (!dicTypes.ContainsKey(typeof(TInterface)))
{
dicTypes.Add(typeof(TInterface), typeof(TImplementation));
}
}
/// <summary>
/// Sign up for a singleton entity
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="instance">单例</param>
public static void Register<T>(T instance) where T : class
{
builder.RegisterInstance(instance).SingleInstance();
}
/// <summary>
/// 构建IOC容器
/// </summary>
public static IServiceProvider Build(IServiceCollection services)
{
//注册程序集
if (otherAssembly != null)
{
foreach (var item in otherAssembly)
{
builder.RegisterAssemblyTypes(Assembly.Load(item));
}
}
//注册类型
if (typesList != null)
{
foreach (var type in typesList)
{
builder.RegisterType(type);
}
}
//注册类型
if (dicTypes != null)
{
foreach (var dicType in dicTypes)
{
builder.RegisterType(dicType.Value).As(dicType.Key);
}
}
//构造容器
builder.Populate(services);
container = builder.Build();
return new AutofacServiceProvider(container);
}
然后在Startup.csCalls in the initialization of the container,Using a container elsewhere in the world won't have to change,在spring.netWhen the configuration is the same with.从实现上看.netcoreContainer implementation of higher point projector,He didn't tube configuration part,Only give you the container to put the function of the object and the object.How do you put objects and take that aleatoric develop.如果简单newObject to write dead into the container and it will be difficult to work.Can configure their analytic reflection object to initialize the container.配置可以是xml、json、Database various can say things.从spring.net的.netcore,Change is the framework,The same is the soul.
iMedicalLISTechnology series article–爱好–产品–事业
边栏推荐
- Linux下常见的开源数据库,你知道几个?
- 21 Days Learning Challenge (2) Use of Graphical Device Trees
- 冒泡排序与快速排序
- rpc-remote procedure call demo
- 2022-08-04 第六小组 瞒春 学习笔记
- ffmpeg 像素格式基础知识
- Shell script: for loop and the while loop
- 2022 High-level installation, maintenance, and removal of exam questions mock exam question bank and online mock exam
- 引领数字医学高地,中山医院探索打造未来医院“新范式”
- Call Alibaba Cloud oss and sms services
猜你喜欢
2022-08-04T17:50:58.296+0800 ERROR Announcer-3 io.airlift.discovery.client.Announcer appears after successful startup of presto
Getting Started with Kubernetes Networking
Hard power or soft power, which is more important to testers?
冰蝎V4.0攻击来袭,安全狗产品可全面检测
21天学习挑战赛(2)图解设备树的使用
银行数据采集,数据补录与指标管理3大问题如何解决?
ASP.NET application--Hello World
【 genius_platform software platform development 】 : seventy-six vs the preprocessor definitions written cow force!!!!!!!!!!(in the other groups conding personnel told so cow force configuration to can
The test salary is so high?20K just graduated
iMedicalLIS监听程序(2)
随机推荐
Redis key基本命令
基于生长的棋盘格角点检测方法
银行数据采集,数据补录与指标管理3大问题如何解决?
Step by step how to perform data risk assessment
[Filter tracking] based on matlab unscented Kalman filter inertial navigation + DVL combined navigation [including Matlab source code 2019]
2022软件测试工程师最全面试题
Android Practical Development - Kotlin Tutorial (Introduction - Login Function Implementation 3.3)
开发Hololens遇到The type or namespace name ‘HandMeshVertex‘ could not be found..
From "useable" to "easy to use", domestic software is self-controllable and continues to advance
.NET应用程序--Helloworld(C#)
龙蜥社区第二届理事大会圆满召开!理事换届选举、4 位特约顾问加入
Dameng 8 database export and import
如何在WordPress中添加特定类别的小工具
2022-08-04 The sixth group, hidden from spring, study notes
包拉链不可用,但是是被另一个包。
Beyond YOLO5-Face | YOLO-FaceV2 officially open source Trick+ academic point full
The second council meeting of the Dragon Lizard Community was successfully held!Director general election, 4 special consultants joined
告白数字化转型时代,时速云镌刻价值新起点
public static
List asList(T... a) What is the prototype? 36-Jenkins-Job Migration