C# 是否可以使用面向方面的方法使用Autofac和DynamicProxy登录Azure函数

C# 是否可以使用面向方面的方法使用Autofac和DynamicProxy登录Azure函数,c#,azure,dependency-injection,autofac,azure-functions,C#,Azure,Dependency Injection,Autofac,Azure Functions,是否可以使用面向方面的方法使用Autofac和DynamicProxy登录Azure函数,方法如下: 我研究了以下链接 然后尝试用下面的代码扩展Holger Leichsenring的帖子(#1)。但是,Intercept()函数从未被激发。有什么想法吗 其他Nuget参考(您还需要将Autofac降级为4.0.1) 睾丸 添加拦截器和带有参数的函数 [Intercept(typeof(ICallLogger))] public class TestIt : ITestIt {

是否可以使用面向方面的方法使用Autofac和DynamicProxy登录Azure函数,方法如下:

我研究了以下链接

  • 然后尝试用下面的代码扩展Holger Leichsenring的帖子(#1)。但是,Intercept()函数从未被激发。有什么想法吗

    其他Nuget参考(您还需要将Autofac降级为4.0.1) 睾丸 添加拦截器和带有参数的函数

    [Intercept(typeof(ICallLogger))]
    public class TestIt : ITestIt
    {
        public string Name { get; set; }
    
        public string CallMe()
        {
            return "Dependency Injection Test method had been called...";
        }
    
        public string CallMeWithParameter(string parameter)
        {
            return "Dependency Injection Test method had been called with [" + parameter + "]";
        }
    }
    
    服务模块
    公共类服务模块:模块
    {
    受保护的覆盖无效负载(ContainerBuilder builder)
    {
    builder.RegisterType().As();
    builder.RegisterType().As().EnableClassInterceptors();
    //如何将上下文传递给AutoFac.ServicesModule()?暂时注释掉,改用无参数构造函数。
    //Register(c=>newcalllogger(context.Trace)).Named(“日志调用”);
    //切换为使用基于类型的拦截器属性,而不是基于名称的拦截器属性
    //Register(c=>newcalllogger()).Named(“日志调用”);
    }
    }
    
    呼叫记录器
    公共接口iCalLogger
    {
    无效拦截(IInvocation调用);
    }
    /// 
    ///希望包装TraceWriter的日志类-现在正在尝试调试输出窗口。。。
    /// 
    公共类调用记录器:IInterceptor,ICallLogger
    {
    TraceWriter\u日志;
    公共调用记录器(TraceWriter日志)
    {
    _log=log;
    }
    公共调用记录器()
    {
    _log=null;
    }
    公共无效拦截(IInvocation调用)
    {
    string message=string.Empty;
    message=“使用参数{1}调用方法{0}…”+
    invocation.Method.Name+
    string.Join(“,”,invocation.Arguments.Select(a=>(a??).ToString()).ToArray();
    如果(_log!=null)
    {
    _日志信息(消息);
    }
    Debug.WriteLine(消息);
    invocation.procedure();
    message=“Done:结果为{0}”。+invocation.ReturnValue;
    Debug.WriteLine(消息);
    如果(_log!=null)
    {
    _日志信息(消息);
    }
    }
    }
    
    这是可以使用的,但正如您所发现的,配置拦截器可能很棘手。我所知道的实现这一点的最简单方法是使用。完全公开,这是我写的一个开源项目。我对自我推销不感兴趣,只是想帮助别人。我之所以在这里提到它,是因为据我所知,这是实现您目标的最简单的方法,如果发布,我很乐意向其他更好的解决方案屈服

    这里有一个完整的要点,您应该能够下载、构建和运行它,它演示了一个简单的日志拦截器。这里有一个简短的解释

  • host.json
    中配置适当的日志级别(请参阅)
  • 添加记录器
    IInterceptor
    实现,它将由自动拾取并注册
  • 添加一个类,该类包含一个或多个
    public
    可重写(即标记为
    virtual
    override
    )方法,您希望拦截这些方法,如所述
  • 使用Functionless的内置orchestrator调用类,或者添加自己的函数触发器来调用类和拦截器
  • 观察截获的日志输出。如果使用前面提到的gist(),它应该产生类似于以下内容的输出(注意以“invoked”结尾的行)
  • 有关无函数如何实现这一点的更多信息,请参阅its,其中包含以下代码片段,如果您希望使用Autofac但不使用无函数实现类似结果,则可以将其应用于许多其他场景

    assemblies.ForEach(
        assembly => builder
            .RegisterAssemblyTypes(assembly)
            .Where(p => p.IsPublic && p.IsClass)
            .AsSelf().AsImplementedInterfaces()
            .PreserveExistingDefaults()
            .EnableClassInterceptors()
            .InterceptedBy(interceptorTypes)
    );
    

    你是否解决了这个问题(面对类似的问题)?确实,有什么进展吗?
    public class ServicesModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterType<CallLogger>().As<ICallLogger>();
            builder.RegisterType<TestIt>().As<ITestIt>().EnableClassInterceptors();
    
            // How can you pass context to the AutoFac.ServicesModule()? Commenting out for now and using parameterless constructor instead.
            // builder.Register(c => new CallLogger(context.Trace)).Named<IInterceptor>("log-calls");
    
            // Switch to use Type based interceptor attribute instead of Name based interceptor attribute
            // builder.Register(c => new CallLogger()).Named<IInterceptor>("log-calls");
    
        }
    }
    
    public interface ICallLogger
    {
        void Intercept(IInvocation invocation);
    }
    
    /// <summary>
    /// Logging class that would hopefully wrap TraceWriter - trying the Debug Output Window for now...
    /// </summary>
    public class CallLogger : IInterceptor, ICallLogger
    {
        TraceWriter _log;
    
        public CallLogger(TraceWriter log)
        {
            _log = log;
        }
    
        public CallLogger()
        {
            _log = null;
        }
    
        public void Intercept(IInvocation invocation)
        {
            string message = string.Empty;
    
            message = "Calling method {0} with parameters {1}... " +
                      invocation.Method.Name +
                      string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray());
    
            if (_log != null)
            {
                _log.Info(message);
            }
    
            Debug.WriteLine(message);
    
            invocation.Proceed();
    
            message = "Done: result was {0}." + invocation.ReturnValue;
            Debug.WriteLine(message);
    
            if (_log != null)
            {
                _log.Info(message);
            }
        }
    }
    
        "logLevel": {
          "FunctionAppLogingInterception": "Debug"
        }
    
        public class LoggingInterceptor : IInterceptor
        {
            public void Intercept(IInvocation invocation)
            {
                ...
            }
        }
    
        public class ReportJob
        {
            [NewOrchestration]
            public virtual async Task ExecuteAsync()
            {
                ...
            }
        }
    
    POST /api/orchestrator?$method=ReportJob.<ExecuteAsync>()
    
    [FunctionName("reportjob-execute")]
    public async Task Execute(
        [HttpTrigger] HttpRequest request,
        [DurableClient] IDurableOrchestrationClient client)
    {
        await client.DurablyInvokeAsync(
            async () => await this.reportJob.ExecuteAsync()
        );
    }
    
    POST /api/reportjob-execute
    
    [2020-12-22T18:20:10.816Z] Host lock lease acquired by instance ID '000000000000000000000000D771FED2'.
    [2020-12-22T18:20:16.207Z] Executing 'orchestrator' (Reason='This function was programmatically called via the host APIs.', Id=bdc7d19e-1250-4692-bde2-98cf663cacb8)
    [2020-12-22T18:20:16.403Z] Executed 'orchestrator' (Succeeded, Id=bdc7d19e-1250-4692-bde2-98cf663cacb8, Duration=243ms)
    [2020-12-22T18:20:16.481Z] Executing 'orchestration' (Reason='(null)', Id=2d17ea99-959c-43ef-b7ba-ed194de38165)
    [2020-12-22T18:20:17.133Z] System.Threading.Tasks.Task ExecuteAsync() invoked
    [2020-12-22T18:20:17.272Z] Executed 'orchestration' (Succeeded, Id=2d17ea99-959c-43ef-b7ba-ed194de38165, Duration=793ms)
    [2020-12-22T18:20:17.339Z] Executing 'orchestration' (Reason='(null)', Id=ff5c08e7-f678-48a3-9a82-bc2e231195e3)
    [2020-12-22T18:20:17.582Z] System.Threading.Tasks.Task GenerateReportsAsync() invoked
    [2020-12-22T18:20:17.597Z] Executed 'orchestration' (Succeeded, Id=ff5c08e7-f678-48a3-9a82-bc2e231195e3, Duration=258ms)
    [2020-12-22T18:20:17.642Z] Executing 'activity' (Reason='(null)', Id=cc4f89ef-f64c-4851-8e7c-3b7acbfcc915)
    [2020-12-22T18:20:17.646Z] Executing 'activity' (Reason='(null)', Id=3a7747a6-5568-4561-a028-9c319263ccf7)
    [2020-12-22T18:20:17.659Z] Executing 'activity' (Reason='(null)', Id=caea5602-9c0b-463a-b0b0-112e512eaf25)
    [2020-12-22T18:20:17.808Z] System.Threading.Tasks.Task GenerateReportAsync() invoked
    [2020-12-22T18:20:17.808Z] System.Threading.Tasks.Task GenerateReportAsync() invoked
    [2020-12-22T18:20:17.808Z] System.Threading.Tasks.Task GenerateReportAsync() invoked
    [2020-12-22T18:20:18.536Z] Executed 'activity' (Succeeded, Id=caea5602-9c0b-463a-b0b0-112e512eaf25, Duration=878ms)
    [2020-12-22T18:20:18.540Z] Executed 'activity' (Succeeded, Id=cc4f89ef-f64c-4851-8e7c-3b7acbfcc915, Duration=901ms)
    [2020-12-22T18:20:18.541Z] Executed 'activity' (Succeeded, Id=3a7747a6-5568-4561-a028-9c319263ccf7, Duration=897ms)
    [2020-12-22T18:20:18.610Z] Executing 'orchestration' (Reason='(null)', Id=9500673c-7c4d-4d91-bfea-b6e095f51197)
    [2020-12-22T18:20:18.716Z] System.Threading.Tasks.Task GenerateReportsAsync() invoked
    [2020-12-22T18:20:18.728Z] Executed 'orchestration' (Succeeded, Id=9500673c-7c4d-4d91-bfea-b6e095f51197, Duration=120ms)
    [2020-12-22T18:20:18.782Z] Executing 'orchestration' (Reason='(null)', Id=8c9dc2d6-71f9-47b0-8c1a-4409da6b23d7)
    [2020-12-22T18:20:18.896Z] System.Threading.Tasks.Task ExecuteAsync() invoked
    [2020-12-22T18:20:18.901Z] Executed 'orchestration' (Succeeded, Id=8c9dc2d6-71f9-47b0-8c1a-4409da6b23d7, Duration=120ms)
    
    assemblies.ForEach(
        assembly => builder
            .RegisterAssemblyTypes(assembly)
            .Where(p => p.IsPublic && p.IsClass)
            .AsSelf().AsImplementedInterfaces()
            .PreserveExistingDefaults()
            .EnableClassInterceptors()
            .InterceptedBy(interceptorTypes)
    );