C# Ninject工厂扩展内存泄漏?

C# Ninject工厂扩展内存泄漏?,c#,.net,ninject,ninject-extensions,C#,.net,Ninject,Ninject Extensions,我使用以下接口作为ToFactory()绑定: public interface ISamplerFactory { ISampler Create(Action<EventHandler<ValueChangedEventArgs>> register, Action<EventHandler<ValueChangedEventArgs>> unregister, Func<decimal?> valueGetter); }

我使用以下接口作为
ToFactory()
绑定:

public interface ISamplerFactory
{
    ISampler Create(Action<EventHandler<ValueChangedEventArgs>> register, Action<EventHandler<ValueChangedEventArgs>> unregister, Func<decimal?> valueGetter);
}
代理中的目标对象已成功GC

我是否做错了什么,或者工厂扩展不是为了处理这些更复杂的参数吗?我假设如果我使用
.WithConstructorArgument
我会得到相同的结果

编辑:添加所有必要的绑定并重写示例代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication
{
    using System;
    using Ninject;
    using Ninject.Extensions.ContextPreservation;
    using Ninject.Extensions.Factory;

    public class Program
    {
        static void Main(string[] args)
        {
            new Program().Run();
        }

        public void Run()
        {
            var kernel = new StandardKernel(new NinjectSettings() { LoadExtensions = false });
            kernel.Load(new FuncModule());
            kernel.Load(new ContextPreservationModule());

            kernel.Bind<IDistributionResolver>().To<DistributionResolver>(); // This is a constructor-less object.
            kernel.Bind<ISampler>().To<SpecificSampler>();
            kernel.Bind<ISamplerFactory>().ToFactory();
            kernel.Bind<IInjected>().To<Injected>();
            kernel.Bind<IDistributionResolver>().To<DistributionResolver>();
            kernel.Bind<IDistributionResolverFactory>().ToFactory();


            var s = new SomeObject();
            var weakS = new WeakReference(s);

            var factory = kernel.Get<ISamplerFactory>();

            var sampler = CreateInstance(factory, s);

            s = null;
            factory = null;
            sampler = null;

            GC.Collect();

            if (weakS.IsAlive)
                throw new Exception();
        }

        private ISampler CreateInstance(ISamplerFactory factory, SomeObject someObject)
        {
            var x = factory.Create(y => someObject.Do += y, z => someObject.Do -= z, () => someObject.Query());

            if (x == null)
                throw new Exception();

            return x;
        }


        public class SomeObject
        {
            public event EventHandler<ValueChangedEventArgs> Do;

            public decimal? Query()
            {
                return 0;
            }
        }

        public class SpecificSampler : ISampler
        {
            private readonly IDistributionResolverFactory resolver;
            private readonly Action<EventHandler<ValueChangedEventArgs>> register;
            private readonly Action<EventHandler<ValueChangedEventArgs>> unregister;
            private Func<decimal?> _valueGetter;

            public SpecificSampler(
                IDistributionResolverFactory resolver, // This is injected
                Action<EventHandler<ValueChangedEventArgs>> register, // The rest come from the factory inputs
                Action<EventHandler<ValueChangedEventArgs>> unregister,
                Func<decimal?> valueGetter)
            {
                this.resolver = resolver;
                this.register = register;
                this.unregister = unregister;
                _valueGetter = valueGetter;
                // Do Stuff;
            }
        }

        public class ValueChangedEventArgs : EventArgs
        {
        }

        public interface ISamplerFactory
        {
            ISampler Create(Action<EventHandler<ValueChangedEventArgs>> register, Action<EventHandler<ValueChangedEventArgs>> unregister, Func<decimal?> valueGetter);
        }

        public interface IDistributionResolverFactory
        {
            IDistributionResolver Create(IDictionary<string, string> picked);
        }

        public interface IDistributionResolver
        {

        }

        private class DistributionResolver : IDistributionResolver
        {
            readonly IInjected _i;
            readonly IDictionary<string, string> _picked;

            public DistributionResolver(IInjected i, IDictionary<string, string> picked)
            {
                _i = i;
                _picked = picked;
            }
        }

        public interface ISampler
        {
        }
    }

    public interface IInjected
    {
    }

    class Injected : IInjected
    {
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
命名空间控制台应用程序
{
使用制度;
使用Ninject;
使用Ninject.Extensions.ContextPreservation;
使用Ninject.Extensions.Factory;
公共课程
{
静态void Main(字符串[]参数)
{
新程序().Run();
}
公开募捐
{
var kernel=new-StandardKernel(new-NinjectSettings(){LoadExtensions=false});
Load(新的FuncModule());
Load(新的ContextPreservationModule());
kernel.Bind().To();//这是一个无构造函数的对象。
kernel.Bind().To();
kernel.Bind().ToFactory();
kernel.Bind().To();
kernel.Bind().To();
kernel.Bind().ToFactory();
var s=新的SomeObject();
var weakS=新的WeakReference;
var factory=kernel.Get();
var sampler=CreateInstance(工厂,s);
s=零;
factory=null;
采样器=空;
GC.Collect();
如果(weakS.IsAlive)
抛出新异常();
}
私有ISampler CreateInstance(ISamplerFactory工厂,SomeObject SomeObject)
{
var x=factory.Create(y=>someObject.Do+=y,z=>someObject.Do-=z,()=>someObject.Query());
如果(x==null)
抛出新异常();
返回x;
}
公共类对象
{
公共事件处理程序Do;
公共十进制查询()
{
返回0;
}
}
公共类特定采样器:ISampler
{
私有只读IDistributionResolver工厂解析器;
私有只读操作寄存器;
私人只读操作取消注册;
私人Func_估价师;
公用采样器(
IDistributionResolverFactory解析器,//这是注入的
动作寄存器,//其余来自工厂输入
取消注册的行动,
Func(估价师)
{
this.resolver=解析器;
this.register=寄存器;
this.unregister=取消注册;
_估价师=估价师;
//做事;
}
}
公共类ValueChangedEventArgs:EventArgs
{
}
公共接口是SampleFactory
{
ISampler Create(操作寄存器、操作注销、Func VALUEGETER);
}
公共接口IDistributionResolverFactory
{
IDistributionResolver创建(IDictionary拾取);
}
公共接口IDistributionResolver
{
}
私有类DistributionResolver:IDistributionResolver
{
只读输入i_i;
只读IDictionary(已拾取);
公共分配冲突解决程序(iIncected i,IDictionary picked)
{
_i=i;
_拾取=拾取;
}
}
公共接口采样器
{
}
}
公共接口输入
{
}
类注入:IInjected
{
}
}

我追踪到Ninject Core中的内存泄漏:


你能添加所有相关的绑定吗?编辑了我的原始帖子。我刚刚修复了工厂扩展中的一个内存泄漏,它是由每个ToFactory绑定上实例化的动态代理引起的。这可能与此有关吗?更多信息请参阅:您好,我做了更多的实验,似乎只有在我将工厂注入工厂时才会发生内存泄漏…请参阅我最初编辑的帖子。谢谢Remo。我不能让你的新代码全部失败。我还尝试在
Collect
之后添加一个
GC.WaitForPendingFinalizers()?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication
{
    using System;
    using Ninject;
    using Ninject.Extensions.ContextPreservation;
    using Ninject.Extensions.Factory;

    public class Program
    {
        static void Main(string[] args)
        {
            new Program().Run();
        }

        public void Run()
        {
            var kernel = new StandardKernel(new NinjectSettings() { LoadExtensions = false });
            kernel.Load(new FuncModule());
            kernel.Load(new ContextPreservationModule());

            kernel.Bind<IDistributionResolver>().To<DistributionResolver>(); // This is a constructor-less object.
            kernel.Bind<ISampler>().To<SpecificSampler>();
            kernel.Bind<ISamplerFactory>().ToFactory();
            kernel.Bind<IInjected>().To<Injected>();
            kernel.Bind<IDistributionResolver>().To<DistributionResolver>();
            kernel.Bind<IDistributionResolverFactory>().ToFactory();


            var s = new SomeObject();
            var weakS = new WeakReference(s);

            var factory = kernel.Get<ISamplerFactory>();

            var sampler = CreateInstance(factory, s);

            s = null;
            factory = null;
            sampler = null;

            GC.Collect();

            if (weakS.IsAlive)
                throw new Exception();
        }

        private ISampler CreateInstance(ISamplerFactory factory, SomeObject someObject)
        {
            var x = factory.Create(y => someObject.Do += y, z => someObject.Do -= z, () => someObject.Query());

            if (x == null)
                throw new Exception();

            return x;
        }


        public class SomeObject
        {
            public event EventHandler<ValueChangedEventArgs> Do;

            public decimal? Query()
            {
                return 0;
            }
        }

        public class SpecificSampler : ISampler
        {
            private readonly IDistributionResolverFactory resolver;
            private readonly Action<EventHandler<ValueChangedEventArgs>> register;
            private readonly Action<EventHandler<ValueChangedEventArgs>> unregister;
            private Func<decimal?> _valueGetter;

            public SpecificSampler(
                IDistributionResolverFactory resolver, // This is injected
                Action<EventHandler<ValueChangedEventArgs>> register, // The rest come from the factory inputs
                Action<EventHandler<ValueChangedEventArgs>> unregister,
                Func<decimal?> valueGetter)
            {
                this.resolver = resolver;
                this.register = register;
                this.unregister = unregister;
                _valueGetter = valueGetter;
                // Do Stuff;
            }
        }

        public class ValueChangedEventArgs : EventArgs
        {
        }

        public interface ISamplerFactory
        {
            ISampler Create(Action<EventHandler<ValueChangedEventArgs>> register, Action<EventHandler<ValueChangedEventArgs>> unregister, Func<decimal?> valueGetter);
        }

        public interface IDistributionResolverFactory
        {
            IDistributionResolver Create(IDictionary<string, string> picked);
        }

        public interface IDistributionResolver
        {

        }

        private class DistributionResolver : IDistributionResolver
        {
            readonly IInjected _i;
            readonly IDictionary<string, string> _picked;

            public DistributionResolver(IInjected i, IDictionary<string, string> picked)
            {
                _i = i;
                _picked = picked;
            }
        }

        public interface ISampler
        {
        }
    }

    public interface IInjected
    {
    }

    class Injected : IInjected
    {
    }
}