方法调用方法时,使用Unity Interception的属性不起作用

时间:2018-08-01 17:26:40

标签: c# dependency-injection attributes unity-container

我正在研究一种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

0 个答案:

没有答案