0

我们使用 UnityContainer 开源 ( https://github.com/unitycontainer ) 版本 5.11.1 进行 DI 和拦截。

web.config(示例)

    <configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration, Version=5.11.2.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0" />
  </configSections>

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration" />

    <container>
      <extension type="Interception"/>

      <register type="Agility.Server.Core.Model.Interfaces.Repository.IResourceRepository, Agility.Server.Core.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948" mapTo="Agility.Server.Repository.SqlServer.ResourceRepository, Agility.Server.Repository.SqlServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948"/>
      <register type="Agility.Server.Core.Model.Interfaces.Repository.IServerRepository, Agility.Server.Core.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948" mapTo="Agility.Server.Repository.SqlServer.ServerRepository, Agility.Server.Repository.SqlServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948"/>
      <register type="Agility.Server.Core.Model.Interfaces.Repository.ITenantRepository, Agility.Server.Core.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948" mapTo="Agility.Server.Repository.SqlServer.TenantRepository, Agility.Server.Repository.SqlServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948"/>
      <register type="Agility.Server.Core.Model.Interfaces.Repository.IThreadPoolRepository, Agility.Server.Core.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948" mapTo="Agility.Server.Repository.SqlServer.ThreadPoolRepository, Agility.Server.Repository.SqlServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948"/>
      <register type="Agility.Server.Core.Model.Interfaces.Repository.IUserRepository, Agility.Server.Core.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948" mapTo="Agility.Server.Repository.SqlServer.UserRepository, Agility.Server.Repository.SqlServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948"/>

      <register type="IMatchingRule" name="AllRule" mapTo="Agility.Server.Common.Logging.AlwaysMatchingRule, Agility.Server.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948" />
      <register type="ICallHandler" name="LogHandler" mapTo="Agility.Server.Common.Logging.LogMethodCallHandler, Agility.Server.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948"/>

      <interception>
        <policy name="webMethods">
          <matchingRule name="AllRule" />
          <callHandler name="LogHandler" />
        </policy>
      </interception>
  </unity>
.....

下面是 AlwaysMatchingRule 的代码

public class AlwaysMatchingRule : IMatchingRule
    {
        
        [InjectionConstructor]
        public AlwaysMatchingRule()
        {
        }

        public bool Matches(MethodBase member)
        {
            return true;
        }
    }

下面是 CallHandler 的代码

public class LogMethodCallHandler : ICallHandler 
    {
        [InjectionConstructor]
        public LogMethodCallHandler()
        {
            this.Order = 0;
        }

        public bool WillExecute
        {
            get { return true; }
        }

        public int Order { get; set; }

        
        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            // Log method invoked, by default we don't log method inputs
            bool logMethodInputs = false; 
            this.LogMethodInvoked(input, logMethodInputs);

            // Invoke the next behavior in the chain.
            IMethodReturn methodReturn = getNext()(input, getNext);

            // Log method completed, by default we don't log method outputs
            bool logMethodOutputs = false;
            this.LogMethodCompleted(input, methodReturn, logMethodOutputs);

            return methodReturn;
        }

        protected void LogMethodInvoked(IMethodInvocation methodInvocation, bool logMethodInputs)
        {
            ArgumentValidator.ValidateForNotNull("methodInvocation", methodInvocation);

            // Before invoking the method on the original target.
            Logger.Log(
                LogMessage.InvokedMethod,
                LogCategory.Information,
                methodInvocation.MethodBase.DeclaringType,
                methodInvocation.MethodBase.Name,
                methodInvocation.MethodBase);
        }

        protected void LogMethodCompleted(
            IMethodInvocation methodInvocation,
            IMethodReturn methodReturn,
            bool logMethodOutputs)
        {
            // After invoking the method on the original target, log the method completion
            if (methodReturn.Exception != null)
            {
                // Log method exception
                Logger.Log(
                    LogMessage.CompletedMethodWithException,
                    LogCategory.Information,
                    methodInvocation.MethodBase.DeclaringType,
                    methodInvocation.MethodBase.Name,
                    methodInvocation.MethodBase,
                    methodReturn.Exception);

                // Log any inner exception
                if (methodReturn.Exception.InnerException != null)
                {
                    bool logAdditionalInformation = false;
                    Logger.Log(
                        LogMessage.InnerException,
                        LogCategory.Information,
                        logAdditionalInformation,
                        methodReturn.Exception.InnerException);
                }
            }
            else
            {
                // Log method method completed
                Logger.Log(
                    LogMessage.CompletedMethod,
                    LogCategory.Information,
                    methodInvocation.MethodBase.DeclaringType,
                    methodInvocation.MethodBase.Name,
                    methodInvocation.MethodBase);
            }
        }
    }

它从不写入日志文件。我们尝试了其他方法并让它在单一类型上工作。

web.config 更改

<configuration>
      <configSections>
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration, Version=5.11.2.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0" />
      </configSections>
    
      <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
        <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration" />
    
        <container>
          <extension type="Interception"/>
    
          <register type="Agility.Server.Core.Model.Interfaces.Repository.IResourceRepository, Agility.Server.Core.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948" mapTo="Agility.Server.Repository.SqlServer.ResourceRepository, Agility.Server.Repository.SqlServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948"/>
          <register type="Agility.Server.Core.Model.Interfaces.Repository.IServerRepository, Agility.Server.Core.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948" mapTo="Agility.Server.Repository.SqlServer.ServerRepository, Agility.Server.Repository.SqlServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948"/>
          <register type="Agility.Server.Core.Model.Interfaces.Repository.ITenantRepository, Agility.Server.Core.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948" mapTo="Agility.Server.Repository.SqlServer.TenantRepository, Agility.Server.Repository.SqlServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948"/>
          <register type="Agility.Server.Core.Model.Interfaces.Repository.IThreadPoolRepository, Agility.Server.Core.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948" mapTo="Agility.Server.Repository.SqlServer.ThreadPoolRepository, Agility.Server.Repository.SqlServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948"/>
          <register type="Agility.Server.Core.Model.Interfaces.Repository.IUserRepository, Agility.Server.Core.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948" mapTo="Agility.Server.Repository.SqlServer.UserRepository, Agility.Server.Repository.SqlServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948">
                <interceptor type="InterfaceInterceptor"/>
                <interceptionBehavior type="Agility.Server.Common.Logging.LogMethodInterceptionBehavior, Agility.Server.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d86c87abe4a71948"/>
          </register>
    
    
      </unity>
    .....

LogMethodInterceptionBehavior 代码

public class LogMethodInterceptionBehavior : IInterceptionBehavior 
    {
        
        public bool WillExecute
        {
            get { return true; }
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }
        
        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            // Log method invoked, by default we don't log method inputs
            bool logMethodInputs = false; 
            this.LogMethodInvoked(input, logMethodInputs);

            // Invoke the next behavior in the chain.
            IMethodReturn methodReturn = getNext()(input, getNext);

            // Log method completed, by default we don't log method outputs
            bool logMethodOutputs = false;
            this.LogMethodCompleted(input, methodReturn, logMethodOutputs);

            return methodReturn;
        }

        protected void LogMethodInvoked(IMethodInvocation methodInvocation, bool logMethodInputs)
        {
            ArgumentValidator.ValidateForNotNull("methodInvocation", methodInvocation);

            // Before invoking the method on the original target.
            Logger.Log(
                LogMessage.InvokedMethod,
                LogCategory.Information,
                methodInvocation.MethodBase.DeclaringType,
                methodInvocation.MethodBase.Name,
                methodInvocation.MethodBase);
        }

        protected void LogMethodCompleted(
            IMethodInvocation methodInvocation,
            IMethodReturn methodReturn,
            bool logMethodOutputs)
        {
            // After invoking the method on the original target, log the method completion
            if (methodReturn.Exception != null)
            {
                // Log method exception
                Logger.Log(
                    LogMessage.CompletedMethodWithException,
                    LogCategory.Information,
                    methodInvocation.MethodBase.DeclaringType,
                    methodInvocation.MethodBase.Name,
                    methodInvocation.MethodBase,
                    methodReturn.Exception);

                // Log any inner exception
                if (methodReturn.Exception.InnerException != null)
                {
                    bool logAdditionalInformation = false;
                    Logger.Log(
                        LogMessage.InnerException,
                        LogCategory.Information,
                        logAdditionalInformation,
                        methodReturn.Exception.InnerException);
                }
            }
            else
            {
                // Log method method completed
                Logger.Log(
                    LogMessage.CompletedMethod,
                    LogCategory.Information,
                    methodInvocation.MethodBase.DeclaringType,
                    methodInvocation.MethodBase.Name,
                    methodInvocation.MethodBase);
            }
        }
    }

方法的问题是我必须将它应用于所有我不想要的类型。有没有办法在一个地方做到这一点并将其应用于所有类型?

我可以使用策略注入方法或 Unity 拦截。

请注意,我希望通过 web.config 进行此操作。

谢谢,阿米特

4

0 回答 0