我遇到了一个我正在研究的项目的问题,即将Ninject WCF Extensions与Interception Extensions结合起来。基本上取决于我如何设置配置,我得到了一些不期望的对象生命周期结果。
我有一些测试代码,其中包含几个显示对象创建和处理的Debug语句。我在IInterceptor创建上看到了一些意想不到的行为。属性拦截,只要我在绑定中正确设置生命周期,一切都按照我期望的方式运行。但是我对绑定拦截感兴趣,例如:
kernel.Bind<MyAspect>().ToSelf().InRequestScope();
kernel.Bind<Service1>().ToSelf().InRequestScope().Intercept().With<MyAspect>();
我希望看到Aspect在每个Wcf服务调用(即虚拟)上创建和处理。我看到的是实际调用的第一个调用上的dispose,然后我没有看到再次调用的创建,但它调用了MyAspect类的原始实例。
我不知道拦截器生命周期是否有最佳实践,但我使用它的情况是应用于此程序集中的每个方法调用(多个服务),用于许多事情,例如记录,限制等等。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service1 : IService1, IDisposable
{
public virtual string GetData(int value)
{
Debug.WriteLine("GetData {0},{1}", value, _id);
return string.Format("You entered: {0},{1}", value, _id);
}
private Guid _id;
public Service1()
{
_id = Guid.NewGuid();
Debug.WriteLine("Service1 constructed {0}", _id);
}
public void Dispose()
{
Debug.WriteLine("Service1 disposed {0}", _id);
}
~Service1()
{
Debug.WriteLine("Service1 finalized {0}", _id);
}
}
[ServiceContract(SessionMode = SessionMode.NotAllowed)]
public interface IService1
{
[OperationContract]
string GetData(int value);
}
public class MyAspect:IInterceptor, IDisposable
{
private Guid _id = Guid.NewGuid();
public MyAspect()
{
Debug.WriteLine("MyAspect create {0}", _id);
}
public void Intercept(IInvocation invocation)
{
Debug.WriteLine("MyAspect Intercept {0}", _id);
invocation.Proceed();
}
public void Dispose()
{
Debug.WriteLine("MyAspect dispose {0}", _id);
}
}
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<MyAspect>().ToSelf().InRequestScope();
kernel.Bind<Service1>().ToSelf().InRequestScope().Intercept().With<MyAspect>();
}
}