我正在研究一种AOP解决方案,用于使用Unity拦截和自定义属性进行日志记录。当直接从main调用方法时,这对方法很有用,但从其他方法调用它们却不起作用。我需要将它们从注入类中调用的任何地方解雇,否则此解决方案将无用。基本设置如下:
创建一个简单的界面和类
public interface IBasicWork
{
Task DoWork();
Task DoWork2();
Task DoAllWork();
}
public class BasicWork : IBasicWork
{
private string constructorString;
public BasicWork(string constructorString)
{
this.constructorString = constructorString;
}
[Log("123")]
public async Task DoWork()
{
Console.WriteLine($"This is the work that I do - {constructorString}");
}
[Log("123")]
public async Task DoWork2()
{
Console.WriteLine($"This is Work2 - {constructorString}");
}
public async Task DoAllWork()
{
await DoWork();
await DoWork2();
}
}
创建自定义日志记录属性和处理程序
public class LogAttribute : HandlerAttribute
{
public string[] Parameters;
public LogAttribute(params string[] parameters)
{
this.Parameters = parameters;
}
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new LoggingAttributeHandler(Parameters);
}
}
public class LoggingAttributeHandler : ICallHandler
{
public int Order { get; set; }
public string[] Parameters;
public LoggingAttributeHandler(params string[] parameters)
{
this.Parameters = parameters;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
Console.WriteLine();
try
{
Console.WriteLine($"Begining of Logging Behavior: {Parameters[0]}");
var methodReturn = getNext()(input, getNext);
Console.WriteLine($"End of Logging Behavior - Success {Parameters[0]}");
return methodReturn;
}
catch (Exception e)
{
// TODO: Failure Client Error Logging Block
Console.WriteLine($"End of Logging Behavior - Failure {Parameters[0]} {e}");
throw;
}
finally
{
Console.WriteLine();
}
}
}
设置Unity容器。
public static class UnityConfig
{
public static string ContructorInjectionObject = "I'm needed";
private static Lazy<IUnityContainer> container =
new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer Container => container.Value;
private static void RegisterTypes(UnityContainer container)
{
container.
AddNewExtension<Interception>().
RegisterType<IBasicWork, BasicWork>(new Interceptor<TransparentProxyInterceptor>(), new InterceptionBehavior<PolicyInjectionBehavior>(),
new InjectionConstructor(ContructorInjectionObject))
.Configure<Interception>()
.AddPolicy("TestPolicy")
.AddCallHandler(new LoggingAttributeHandler());
}
}
然后将BasicWork类插入Program.Main()中,以查看其运行情况。
class Program
{
static void Main(string[] args)
{
var bw = UnityConfig.Container.Resolve<IBasicWork>();
bw.DoAllWork();
bw.DoWork();
bw.DoWork2();
}
}
输出显示,当从Program.Main中调用bw.DoWork()和bw.DoWork2时,将触发LoggingAttribute。但是当DoAllWork调用这两个方法时,它们不会触发该属性。
我在这里想念什么?这会在Unity或自定义属性的一部分中发生吗?甚至不确定我将如何调试它。
输出:
This is the work that I do - I'm needed
This is Work2 - I'm needed
Begining of Logging Behavior: 123
This is the work that I do - I'm needed
End of Logging Behavior - Success 123
Begining of Logging Behavior: 123
This is Work2 - I'm needed
End of Logging Behavior - Success 123