Soru Ninject, Func'i (otomatik olarak üretilmiş fabrika) destekliyor mu?


Autofac otomatik olarak fabrikalar üretir Func<T>; Parametreleri bile geçebilirim.

public class MyClass
{
    public MyClass(Func<A> a, Func<int, B> b)
    {
        var _a = a();
        var _b = b(1);
    }
}

Aynısını Ninject ile yapabilir miyim? Değilse, hangi geçici çözümü uygulayabilirim?

Teşekkürler.

Güncelleştirme:

Sadece bu yazıyı buldum, cevap şu ki:

Ninject ile sınıfları statik yöntemlerle nasıl işlerim?


21
2018-01-29 23:35


Menşei




Cevaplar:


NB Ninject 3.0 ve üstü bunu kullanarak tamamen destekleniyor. Ninject.Extensions.Factory paket, wiki'ye bakın: - https://github.com/ninject/ninject.extensions.factory/wiki


EDIT: NB var bir Bind<T>().ToFactory() Ninject 2.3'te uygulama (tam olarak desteklenen bir sürüm değildir, ancak CodeBetter sunucusundan kullanılabilir)

Ninject bunu şu anda yerel olarak desteklemiyor. Bunu bir sonraki sürüme eklemeyi planladık. Ancak, uygun bağlamayı yapılandırarak destek kolayca eklenebilir. Sadece aşağıdaki modülü yükleyin ve keyfini çıkarın.

public class FuncModule : NinjectModule
{
    public override void Load()
    {
        this.Kernel.Bind(typeof(Func<>)).ToMethod(CreateFunc).When(VerifyFactoryFunction);
    }

    private static bool VerifyFactoryFunction(IRequest request)
    {
        var genericArguments = request.Service.GetGenericArguments();
        if (genericArguments.Count() != 1)
        {
            return false;
        }

        var instanceType = genericArguments.Single();
        return request.ParentContext.Kernel.CanResolve(new Request(genericArguments[0], null, new IParameter[0], null, false, true)) ||
               TypeIsSelfBindable(instanceType);
    }

    private static object CreateFunc(IContext ctx)
    {
        var functionFactoryType = typeof(FunctionFactory<>).MakeGenericType(ctx.GenericArguments);
        var ctor = functionFactoryType.GetConstructors().Single();
        var functionFactory = ctor.Invoke(new object[] { ctx.Kernel });
        return functionFactoryType.GetMethod("Create").Invoke(functionFactory, new object[0]);
    }

    private static bool TypeIsSelfBindable(Type service)
    {
        return !service.IsInterface
               && !service.IsAbstract
               && !service.IsValueType
               && service != typeof(string)
               && !service.ContainsGenericParameters;
    }

    public class FunctionFactory<T>
    {
        private readonly IKernel kernel;

        public FunctionFactory(IKernel kernel)
        {
            this.kernel = kernel;
        }

        public Func<T> Create()
        {
            return () => this.kernel.Get<T>();
        }
    }
}

29
2018-01-31 14:16



Kod için teşekkürler! Bir sonraki versiyon için sabırsızlıkla beklerim.
Tüm sıkı çalışman için teşekkürler Remo. Kodu Func <IEnumerable <T >> ile çalışmak için genişletmek mümkün mü? - Anders
Tabiki öyle. FunctionFactory.Create yöntemini değiştirin, IEnumerable için işaretleyin ve GetAll yerine döndürün. - Remo Gloor
Süper hızlı cevap! : D Ama bu Func <IEnumerable <T >> (nerede benim arayüzeyim) için bir bağlayıcı bulamadığını şikayet ediyor .. tam hata mesajı ... Func {IEnumerable {IWorker}} 2) Bağımlılık Enjeksiyonu Func {IEnumerable {IWorker}}, WorkflowManager türünde kurucunun workerFactory parametresine - Anders
Ah, fark ettim ki, VerifyFactoryFunction'a kadar, bunun işe yaraması için onu güncellemeliyim .. teşekkürler dostum! - Anders