如何在组件被处置之前运行一段代码?
我正在使用 castle-windsor 框架,并且我想在框架发布特定(第三方)组件之前调用一段代码。
我认为可以通过向 OnDestroy
添加委托来实现此目的,但框架始终首先调用 Dispose
。 (参见下面的示例)。
在调用 Dispose
之前,我必须使用哪些选项来调用代码?
public class TestClass : IDisposable
{
static long _globalInstanceCount = 0;
readonly long _instanceId;
public TestClass()
{
_instanceId = Interlocked.Increment(ref _globalInstanceCount);
Trace.WriteLine(string.Format("TestClass ({0}) - Constructor called", _instanceId));
}
public void ByeBye()
{
Trace.WriteLine(string.Format("TestClass ({0}) - ByeBye called", _instanceId));
}
void IDisposable.Dispose()
{
Trace.WriteLine(string.Format("TestClass ({0}) - Dispose called", _instanceId));
}
}
class Program
{
static void Main(string[] args)
{
{
Trace.WriteLine("Testing as a singleton");
var container = new WindsorContainer()
.Register(Component.For<TestClass>()
.LifeStyle.Singleton
.OnDestroy(t => t.ByeBye())
);
TestClass tc = container.Resolve<TestClass>();
Trace.WriteLine("Releasing the component");
container.Release(tc);
Trace.WriteLine("Disposing of the container");
container.Dispose();
}
{
Trace.WriteLine("Testing transient");
var container = new WindsorContainer()
.Register(Component.For<TestClass>()
.LifeStyle.Transient
.OnDestroy(t => t.ByeBye())
);
TestClass tc = container.Resolve<TestClass>();
Trace.WriteLine("Releasing the component");
container.Release(tc);
Trace.WriteLine("Disposing of the container");
container.Dispose();
}
}
}
这会产生以下输出。如您所见,ByeBye
在 Dispose
之后调用。
作为单例进行测试
TestClass (1) - 构造函数调用
释放组件
容器的处置
TestClass (1) - 调用 Dispose
TestClass (1) - ByeBye 被调用
测试瞬态
TestClass (2) - 构造函数调用
释放组件
TestClass (2) - 调用 Dispose
TestClass (2) - ByeBye 被调用
容器的处置
我尝试使用拦截器解决此问题,但事实证明,Windsor 框架调用 Dispose
在原始组件上绕过任何拦截器。
Trace.WriteLine("Testing transient with interceptor");
var container = new WindsorContainer()
.Register(Component.For<TestClassInterceptor>().LifeStyle.Transient,
Component.For<TestClass>()
.LifeStyle.Transient
.OnDestroy(t => t.ByeBye())
.Interceptors<TestClassInterceptor>()
);
TestClass tc = container.Resolve<TestClass>();
tc.Hello();
Trace.WriteLine("Releasing the component");
container.Release(tc);
Trace.WriteLine("Disposing of the container");
container.Dispose();
产生以下输出。请注意,TestClass (3) - Dispose
的调用与拦截器无关。
使用拦截器测试瞬态
TestClassInterceptor (1) - 构造函数调用
TestClass (3) - 构造函数调用
TestClassInterceptor(一)-拦截方法“Hello”
TestClass (3) - 你好,叫来
释放组件
TestClass (3) - 调用 Dispose
TestClassInterceptor(一)-拦截方法“ByeBye”
TestClass (3) - 再见
TestClassInterceptor (1) - Dispose 调用
容器的处置
I am using the castle-windsor framework, and I want to invoke a piece of code just before the framework releases a specific (third-party) component.
I thought that I could do this by adding a delegate to OnDestroy
, but the framework always calls Dispose
first. (See example below).
What options do I have to invoke the code before Dispose
is called?
public class TestClass : IDisposable
{
static long _globalInstanceCount = 0;
readonly long _instanceId;
public TestClass()
{
_instanceId = Interlocked.Increment(ref _globalInstanceCount);
Trace.WriteLine(string.Format("TestClass ({0}) - Constructor called", _instanceId));
}
public void ByeBye()
{
Trace.WriteLine(string.Format("TestClass ({0}) - ByeBye called", _instanceId));
}
void IDisposable.Dispose()
{
Trace.WriteLine(string.Format("TestClass ({0}) - Dispose called", _instanceId));
}
}
class Program
{
static void Main(string[] args)
{
{
Trace.WriteLine("Testing as a singleton");
var container = new WindsorContainer()
.Register(Component.For<TestClass>()
.LifeStyle.Singleton
.OnDestroy(t => t.ByeBye())
);
TestClass tc = container.Resolve<TestClass>();
Trace.WriteLine("Releasing the component");
container.Release(tc);
Trace.WriteLine("Disposing of the container");
container.Dispose();
}
{
Trace.WriteLine("Testing transient");
var container = new WindsorContainer()
.Register(Component.For<TestClass>()
.LifeStyle.Transient
.OnDestroy(t => t.ByeBye())
);
TestClass tc = container.Resolve<TestClass>();
Trace.WriteLine("Releasing the component");
container.Release(tc);
Trace.WriteLine("Disposing of the container");
container.Dispose();
}
}
}
This produces the following output. As you can see, ByeBye
is called after Dispose
.
Testing as a singleton
TestClass (1) - Constructor called
Releasing the component
Disposing of the container
TestClass (1) - Dispose called
TestClass (1) - ByeBye called
Testing transient
TestClass (2) - Constructor called
Releasing the component
TestClass (2) - Dispose called
TestClass (2) - ByeBye called
Disposing of the container
I have attempted to solve this using an interceptor, but it turns out that the Windsor framework calls Dispose
on the original component bypassing any interceptors.
Trace.WriteLine("Testing transient with interceptor");
var container = new WindsorContainer()
.Register(Component.For<TestClassInterceptor>().LifeStyle.Transient,
Component.For<TestClass>()
.LifeStyle.Transient
.OnDestroy(t => t.ByeBye())
.Interceptors<TestClassInterceptor>()
);
TestClass tc = container.Resolve<TestClass>();
tc.Hello();
Trace.WriteLine("Releasing the component");
container.Release(tc);
Trace.WriteLine("Disposing of the container");
container.Dispose();
Results in the following output. See that TestClass (3) - Dispose
is called independently of the interceptor.
Testing transient with interceptor
TestClassInterceptor (1) - Constructor called
TestClass (3) - Constructor called
TestClassInterceptor (1) - Intecepting Method "Hello"
TestClass (3) - Hello called
Releasing the component
TestClass (3) - Dispose called
TestClassInterceptor (1) - Intecepting Method "ByeBye"
TestClass (3) - ByeBye called
TestClassInterceptor (1) - Dispose called
Disposing of the container
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论