メソッドが特定の属性で装飾されている場合、メソッド呼び出しをインターセプトするように Unity をセットアップしています。すべての Unity プロキシ オブジェクトを (一時的ではなく) 各スレッド内で持続させたいと考えています。
問題は、装飾属性によって作成されたオブジェクトが毎回「新しく」作成されることです。属性内から UnityContainer にアクセスする方法がわかりません。可能であれば、LogHandler をスレッドごとのエンティティとして作成し、Unity 経由でリクエストします。(これは意味がありますか?ユニティを使用して、ユニティ インターセプトで使用されるオブジェクトを解決しますか?)。
このコードを実行すると、ロガーによるカウント出力は常に「1」になります。明確にするために、この「LogHandler」は私が永続化したいものです。
コードの他の場所で Unity を介してオブジェクトをどのように解決しますか? Unityコンテナを回しますか?コードのどこからでもリクエストできるパターンはありますか?
using System;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
namespace UnityTest2
{
class Program
{
private static UnityContainer _uC;
static void Main(string[] args)
{
_uC = new UnityContainer();
_uC.AddNewExtension<Interception>();
_uC.Configure<Interception>().SetInterceptorFor<ICalc>(new InterfaceInterceptor());
_uC.RegisterType<ICalc, Calc>( new PerThreadLifetimeManager() );
var c = _uC.Resolve<ICalc>();
Console.WriteLine(c.Add(3, 7));
Console.WriteLine(c.Sub(3, 7));
Console.ReadKey();
}
}
public class LogAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
// I want this to persist per thread
return new LogHandler();
}
}
public class LogHandler : ICallHandler
{
private int runCount = 0;
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
runCount++;
// this is always '1'
Console.WriteLine(runCount);
return getNext()(input, getNext);
}
public int Order { get; set; }
}
public interface ICalc
{
int Add(int x, int y);
int Sub(int x, int y);
int Mul(int x, int y);
}
public class Calc : ICalc
{
[Log]
public int Add(int x, int y)
{
return x + y;
}
[Log]
public int Sub(int x, int y)
{
return x - y;
}
public int Mul(int x, int y)
{
return x * y;
}
}
}