1

I've run into an issue with a project I'm working on that is combining the Ninject WCF Extensions with the Interception Extensions. Basically depending on how I setup my configuration, I'm getting some different object lifetime results that are not expected.

I've got some test code with several Debug statements showing object creation and disposal. I'm seeing some unexpected behavior on the IInterceptor creation. Attribute Interception, as long as I then properly set the lifetime in bindings, everything behaves the way I expect. However I'm interested binding interception such as:

        kernel.Bind<MyAspect>().ToSelf().InRequestScope();
        kernel.Bind<Service1>().ToSelf().InRequestScope().Intercept().With<MyAspect>();

I would expect to see the Aspect created and disposed on every Wcf service call (that is virtual). What I see is the dispose on the first call actually called, and then I do not see a create called again, but it calls the original instance of the MyAspect class.

I don't know if there is a best practice in terms of the Interceptors lifetime, however the situation I'm using this for is to be applied to every method call in this assembly (multiple services) for many things, such as logging, some throttling, etc.

[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>();
    }        
}
  • I know it has been a while since this was asked. I ran into the same issue, I ended up using this.. `invocation.Request.Kernel.Get()` – paulio Aug 11 '16 at 21:29

0 Answers0