簡體   English   中英

Ninject獲取當前創建的所有實例?

[英]Ninject get all instances created at the moment?

有沒有辦法檢索已經實例化但尚未處理的IMyInterface列表? 例如:

public interface IMyInterface : IDisposable {} //IDisposable will be called by Ninject when object collected by GC

public class MyModule : NinjectModule
{
    public override void Load()
    {
        Bind<IMyInterface>().To<MyImplementation>();//creates new instance on every Get<> call
    }
}

var a = kernel.Get<IMyInterface>();
var b = kernel.Get<IMyInterface>();
var c = kernel.Get<IMyInterface>();

var abcList = kernel.GetCurrentInstances<IMyInterface>(); // list contains [a,b,c] instances, because they are not collected at this point

雖然我不知道這樣做的可行方法,但是您可以使用ActivationActions輕松實現這一目標。 這使您可以指定在為特定綁定創建對象時要執行的功能。 然后,您可以擁有一個ObjectTracker<T>類,該類使用弱引用來跟蹤特定類的實例化:

public static class BindingExtension
{
    public static IBindingToSyntax<TInterface> TrackObjects<TInterface>(this IBindingToSyntax<TInterface> self)
        where TInterface : class
    {

        self.Kernel.Bind<ObjectTracker<TInterface>>().ToSelf().InSingletonScope();
        self.BindingConfiguration.ActivationActions.Add((c, o) =>
        {
            c.Kernel.Get<ObjectTracker<TInterface>>().Add((TInterface)o);
        });

        return self;
    }
}
// Usage
public class MyModule : NinjectModule
{
    public override void Load()
    {
        Bind<IMyInterface>()
            .TrackObjects()
            .To<MyImplementation>();//creates new instance on every Get<> call
    }
}

var a = kernel.Get<IMyInterface>();
var b = kernel.Get<IMyInterface>();
var c = kernel.Get<IMyInterface>();

var abcList = kernel.Get<ObjectTracker<IMyInterface>>().AllInstances.ToList();

// Helper class
public class ObjectTracker<T>
    where T: class
{
    private List<WeakReference<T>> instances = new List<WeakReference<T>>();
    public void Add(T item)
    {
        this.Prune(); // You could optimize how often you prune the list, with a counter for example.
        instances.Add(new WeakReference<T>(item));
    }
    public void Prune()
    {
        this.instances.RemoveAll(x => !x.TryGetTarget(out var _));
    }
    public IEnumerable<T> AllInstances => instances
        .Select(x =>
        {
            x.TryGetTarget(out var target);
            return target;
        })
        .Where(x => x != null);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM