dotnet核心中的RealProxy?

问题描述 投票:28回答:3

我正在使用命名空间System.Runtime.Remoting.ProxiesSystem.Runtime.Remoting.Messaging在C#中进行AOP。我正在尝试将我的应用程序从.Net Framework 4.6移植到dnxcore / dotnet核心。

Intellisense说,这两个命名空间不适用于我的framework-vesion(netcoreapp1.0 / dnxcore50)。知道这两个命名空间是否会出现?或者任何想法如何获得与RealProxy级一样的AOP?

我不想使用第三方库 - 我只想使用.Net提供给我的东西。

c# aop dnx .net-core
3个回答
33
投票

It looks like RealProxy won't come to .NET Core/Standard。在这个问题上,微软开发人员建议将DispatchProxy作为替代方案。

此外,一些现有的AOP框架可能已经或将来支持.NET Core(如对问题的评论中所见)。

另一种选择是DispatchProxy,这里有一个很好的例子:http://www.c-sharpcorner.com/article/aspect-oriented-programming-in-c-sharp-using-dispatchproxy/

如果我们简化代码,这就是我们得到的:

public class LoggingDecorator<T> : DispatchProxy
{
    private T _decorated;

    protected override object Invoke(MethodInfo targetMethod, object[] args)
    {
        try
        {
            LogBefore(targetMethod, args);

            var result = targetMethod.Invoke(_decorated, args);

            LogAfter(targetMethod, args, result);
            return result;
        }
        catch (Exception ex) when (ex is TargetInvocationException)
        {
            LogException(ex.InnerException ?? ex, targetMethod);
            throw ex.InnerException ?? ex;
        }
    }

    public static T Create(T decorated)
    {
        object proxy = Create<T, LoggingDecorator<T>>();
        ((LoggingDecorator<T>)proxy).SetParameters(decorated);

        return (T)proxy;
    }

    private void SetParameters(T decorated)
    {
        if (decorated == null)
        {
            throw new ArgumentNullException(nameof(decorated));
        }
        _decorated = decorated;
    }

    private void LogException(Exception exception, MethodInfo methodInfo = null)
    {
        Console.WriteLine($"Class {_decorated.GetType().FullName}, Method {methodInfo.Name} threw exception:\n{exception}");
    }

    private void LogAfter(MethodInfo methodInfo, object[] args, object result)
    {
        Console.WriteLine($"Class {_decorated.GetType().FullName}, Method {methodInfo.Name} executed, Output: {result}");
    }

    private void LogBefore(MethodInfo methodInfo, object[] args)
    {
        Console.WriteLine($"Class {_decorated.GetType().FullName}, Method {methodInfo.Name} is executing");
    }
}

因此,如果我们有一个带有相应接口的示例类Calculator(此处未显示):

public class Calculator : ICalculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

我们可以像这样简单地使用它

static void Main(string[] args)
{
    var decoratedCalculator = LoggingDecorator<ICalculator>.Create(new Calculator());
    decoratedCalculator.Add(3, 5);
    Console.ReadKey();
}

8
投票

您可以使用System.Reflection.DispatchProxy或您自己的简单装饰器实现。检查维基百科上的Decorator pattern页面以获取实施示例。

目前在.NET Core中,您无法使用DispatchProxy构造函数注入。您必须使用DispatchProxy.Create()工厂方法和属性注入以及要使用的显式强制转换为代理类型。有关更多信息,请查看.NET Core GitHub存储库中的DispachProxyTest.cs

这是一个继承DispatchProxy的简单通用装饰器的示例:

class GenericDecorator : DispatchProxy
{
    public object Wrapped { get; set; }
    public Action<MethodInfo, object[]> Start { get; set; }
    public Action<MethodInfo, object[], object> End { get; set; }
    protected override object Invoke(MethodInfo targetMethod, object[] args)
    {
        Start?.Invoke(targetMethod, args);
        object result = targetMethod.Invoke(Wrapped, args);
        End?.Invoke(targetMethod, args, result);
        return result;
    }
}

它的用法:

class Program
{
    static void Main(string[] args)
    {
        IEcho toWrap = new EchoImpl();
        IEcho decorator = DispatchProxy.Create<IEcho, GenericDecorator>();
        ((GenericDecorator)decorator).Wrapped = toWrap;
        ((GenericDecorator)decorator).Start = (tm, a) => Console.WriteLine($"{tm.Name}({string.Join(',', a)}) is started");
        ((GenericDecorator)decorator).End = (tm, a, r) => Console.WriteLine($"{tm.Name}({string.Join(',', a)}) is ended with result {r}");
        string result = decorator.Echo("Hello");
    }

    class EchoImpl : IEcho
    {
        public string Echo(string message) => message;
    }

    interface IEcho
    {
        string Echo(string message);
    }
}

1
投票

您还可以使用Autofac和DynamicProxy的组合。本文有一个很好的介绍和如何完成它的示例。

AOP in .Net Core

© www.soinside.com 2019 - 2024. All rights reserved.