Перехват Ninject и расширения WCF, управление временем жизни перехватчика
У меня возникла проблема с проектом, над которым я работаю, который объединяет расширения Ninject WCF и расширения перехвата. В основном, в зависимости от того, как я настраиваю свою конфигурацию, я получаю некоторые другие результаты времени жизни объекта, которые не ожидаются.
У меня есть тестовый код с несколькими операторами Debug, показывающими создание и удаление объектов. Я вижу неожиданное поведение при создании II-рецептора. Перехват атрибутов, пока я правильно устанавливаю время жизни в привязках, все ведет себя так, как я ожидаю. Однако меня интересует обязательный перехват, такой как:
kernel.Bind<MyAspect>().ToSelf().InRequestScope();
kernel.Bind<Service1>().ToSelf().InRequestScope().Intercept().With<MyAspect>();
Я ожидал бы увидеть Аспект, созданный и расположенный при каждом вызове службы Wcf (то есть виртуальный). То, что я вижу, - это удаление по первому вызову, фактически вызванному, и затем я не вижу, что вызов вызывается снова, но он вызывает исходный экземпляр класса 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>();
}
}