我使用Unity设置来在使用特定属性修饰方法时拦截方法调用。我希望所有Unity代理对象都在每个线程中保留(而不是瞬态)。
问题是,decoration属性创建的对象每次都创建为“new”。我看不到从属性中访问UnityContainer的方法。如果可以的话,我会将LogHandler创建为每线程实体并通过Unity请求它。 (这是否有意义?使用Unity来解析统一拦截中使用的对象?)。
如果运行此代码,则记录器的计数输出始终为“1”。要清楚,这个'LogHandler'就是我想要坚持的。
如何通过代码中的其他地方统一解析对象?你绕过统一容器吗?我可以使用一种模式从我的代码中的任何地方请求它吗?
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;
}
}
}
答案 0 :(得分:2)
您可以在启动期间使用PerThreadLifetimeManager向Unity注册您的呼叫处理程序。
_uC.RegisterType<LoggingCallHandler>(new PerThreadLifetimeManager());
然后该属性可以从容器中解析处理程序:
public class LoggingAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return container.Resolve<LoggingCallHandler>();
}
}
通常,您不希望传递容器的实例,因为这会将您的应用程序与所使用的特定容器紧密耦合。这将使用容器作为Service Locator。很多人认为这是anti-pattern。
调用处理程序属性是Unity基础结构的一部分(适用于您的应用程序);它们扩展了Unity的抽象HandlerAttribute
并要求CreateHandler方法接受IUnityContainer,因此使用HandlerAttribute中的容器并不是意料之外的。