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>();
答
它看起来像你对我缺少DynamicProxy
为IPortfolio
和IInterceptor
类型之间的关联。
这可以通过注册得到纠正:
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);
}
开不工作,我很害怕,我已经更新了我的问题与您的代码的建议...我认为问题在于Portfolio取得了Shareholding.Factory委托的依赖关系,并且IQuoteService在Shareholding的构造函数上得到了解决。 – Codebrain