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
{
}
}