2016-12-30 4 views
2

私は & タイプインターセプタがお互いにうまくプレーするAutoFac デリゲート工場を取得しようとしていますが、私は私が望む行動を取得するように見えることはできませんが。Autofac - 委任工場+型迎撃一緒

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

以下の例では、私はIQuoteService.GetQuote(...)への呼び出しがCallLoggerインターセプタで傍受されたいです。

私はEnable ___()を試しました。インターセプトを有効にするための拡張メソッドですが、それらのどれも正しくコールを傍受していないようです。

私はAutofacが代理人と代理人の署名を登録している方法だと思っていますが、正直言って私はちょっと立ち往生しています...私はAutofacも知っているだけでなく、このプロジェクトはAutofacを使用しています。あなたはIPortfolioためDynamicProxyIInterceptorタイプとの関連性を欠けているようですが、私には見えます

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(); 
     } 
    } 
} 

答えて

2
// 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

Does't仕事を経由して、私はあなたのコードの提案で私の質問を更新しました...ポートフォリオは株式保有者の従業員に依存しており、IQuoteServiceは株式保有者のコンストラクタで解決されるという問題があると私は信じています。 – Codebrain

2

は、以下の実施例に更新

コードを答えました。これは、登録を経て改善することができる

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); 
}