Autofac - 委托工厂+型拦截器一起

问题描述:

我试图让AutoFac 委托工厂 & 型拦截相互发挥很好,但我似乎无法得到我想要的行为。Autofac - 委托工厂+型拦截器一起

http://docs.autofac.org/en/latest/advanced/delegate-factories.html) (http://docs.autofac.org/en/latest/advanced/interceptors.html

在下面的例子中,我想将IQuoteService.GetQuote(...)调用由CallLogger拦截器拦截。

我都试过的启用___();用于启用拦截的扩展方法,但它们中没有一个似乎正确地拦截该呼叫。

我怀疑问题是Autofac注册代理和代理签名的方式,但说实话我有点卡住......我不知道Autofac和我所知道的温莎城堡一样,但是这个项目正在使用Autofac。

以下内容得到更新工作示例

代码:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using Autofac; 
using Autofac.Extras.DynamicProxy2; 
using Castle.DynamicProxy; 

namespace AutofacTest 
{ 
    public class Shareholding 
    { 
     public delegate Shareholding Factory(string symbol, uint holding); 

     private readonly IQuoteService _quoteService; 

     public Shareholding(string symbol, uint holding, IQuoteService quoteService) 
     { 
      _quoteService = quoteService; 
      Symbol = symbol; 
      Holding = holding; 
     } 

     public string Symbol { get; private set; } 

     public uint Holding { get; set; } 

     public decimal Value 
     { 
      get { return _quoteService.GetQuote(Symbol) * Holding; } 
     } 
    } 

    public class Portfolio 
    { 
     private readonly IList<Shareholding> _holdings = new List<Shareholding>(); 
     private readonly Shareholding.Factory _shareholdingFactory; 

     public Portfolio(Shareholding.Factory shareholdingFactory) 
     { 
      _shareholdingFactory = shareholdingFactory; 
     } 

     public decimal Value 
     { 
      get { return _holdings.Sum(h => h.Value); } 
     } 

     public void Add(string symbol, uint holding) 
     { 
      _holdings.Add(_shareholdingFactory(symbol, holding)); 
     } 
    } 

    public interface IQuoteService 
    { 
     decimal GetQuote(string symbol); 
    } 

    public class QuoteService : IQuoteService 
    { 
     public decimal GetQuote(string symbol) 
     { 
      return 10m; 
     } 
    } 

    public class CallLogger : IInterceptor 
    { 
     private readonly TextWriter _output; 

     public CallLogger(TextWriter output) 
     { 
      _output = output; 
     } 

     public void Intercept(IInvocation invocation) 
     { 
      _output.Write("Calling method {0} with parameters {1}... ", 
       invocation.Method.Name, 
       string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray())); 

      invocation.Proceed(); 

      _output.WriteLine("Done: result was {0}.", invocation.ReturnValue); 
     } 
    } 

    internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      var builder = new ContainerBuilder(); 
      builder.RegisterType<Shareholding>(); 
      builder.RegisterType<Portfolio>(); 
      builder.Register(c => new CallLogger(Console.Out)); 

      builder.RegisterType<QuoteService>() 
        .As<IQuoteService>() 
        .EnableInterfaceInterceptors() 
        .InterceptedBy(typeof(CallLogger)); 

      var container = builder.Build(); 

      var portfolio = container.Resolve<Portfolio>(); 
      portfolio.Add("ABC", 1234); 
      portfolio.Add("DEF", 4567); 

      Console.WriteLine(portfolio.Value); 
      Console.ReadKey(); 
     } 
    } 
} 

// Magic? 

builder.RegisterType<Portfolio>() 
     .As<IPortfolio>() 
     .EnableInterfaceInterceptors() 
     .InterceptedBy(typeof(CallLogger));; 
builder.Register(c => new CallLogger(Console.Out)); 
var container = builder.Build(); 
var isResolved = container.Resolve<IPortfolio>(); 
+0

开不工作,我很害怕,我已经更新了我的问题与您的代码的建议...我认为问题在于Portfolio取得了Shareholding.Factory委托的依赖关系,并且IQuoteService在Shareholding的构造函数上得到了解决。 – Codebrain

它看起来像你对我缺少DynamicProxyIPortfolioIInterceptor类型之间的关联。

这可以通过注册得到纠正:

builder.RegisterType<Portfolio>() 
    .As<IPortfolio>() 
    .EnableInterfaceInterceptors() 
    .InterceptedBy(typeof(CallLogger)); 

,或者通过InterceptAttribute

[Intercept(typeof(CallLogger))] 
public interface IPortfolio 
{ 
    decimal Value { get; } 
    void Add(string symbol, uint holding); 
}