2016-12-30 66 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攔截器攔截。

我都試過的啓用___();用於啓用攔截的擴展方法,但它們中沒有一個似乎正確地攔截該呼叫。

我懷疑問題是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(); 
     } 
    } 
} 

回答

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

開不工作,我很害怕,我已經更新了我的問題與您的代碼的建議...我認爲問題在於Portfolio取得了Shareholding.Factory委託的依賴關係,並且IQuoteService在Shareholding的構造函數上得到了解決。 – Codebrain

2

它看起來像你對我缺少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); 
}